今天开始接触Netty这个NIO框架,由与MINA同一作者创作的框架,在看过User Guide 3.6之后,API风格与使用方式与MINA2大致类似。作为学习新框架的起始,先来几个Hello World程序吧。
看API依然是基于Reactor模型,程序分三部分
1.事件处理程序
主要包括对具体业务消息的处理,对各种连接状态的响应
public class TimeServerHandler extends SimpleChannelHandler {
@Override
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) {
Channel ch = e.getChannel();
ChannelBuffer time = ChannelBuffers.buffer(4);
time.writeInt((int) (System.currentTimeMillis() / 1000L + 2208988800L));
ChannelFuture f = ch.write(time);
f.addListener(new ChannelFutureListener() {
public void operationComplete(ChannelFuture future) {
Channel ch = future.getChannel();
ch.close();
}
});
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
e.getCause().printStackTrace();
e.getChannel().close();
}
}
2.编解码器
在大流量数据传输时的必备品,在流传输的基础根据业务情况分隔出数据包处理,ChannelBuffer转成POJO比较适合在解码器中进行。
package org.jboss.netty.example.time;
public class TimeDecoder extends FrameDecoder(22) {
@Override
protected Object decode(
ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) {
if (buffer.readableBytes() < 4) {//如果不够数据,返回空对象,不处理
return null; (24)
}
return buffer.readBytes(4);(25)
}
}
解码器不需要递归调用直到数据解析完毕,框架会自动调动直到把已接收的数据处理完毕。
另一个非常方便的解码器是ReplayingDecoder,它假设在解码时已经有足够的数据,如:
public class IntegerHeaderFrameDecoder
extends ReplayingDecoder<VoidEnum> {
protected Object decode(ChannelHandlerContext ctx,
Channel channel,
ChannelBuffer buf,
VoidEnum state) throws Exception {
return buf.readBytes(buf.readInt());
}
}
编码器使用如下
public class TimeEncoder extends SimpleChannelHandler {
public void writeRequested(ChannelHandlerContext ctx, MessageEvent(27) e) {
UnixTime time = (UnixTime) e.getMessage();
ChannelBuffer buf = buffer(4);
buf.writeInt(time.getValue());
Channels.write(ctx, e.getFuture(), buf);(28)
}
}
3.主体程序
服务器端:
public class DiscardServer {
public static void main(String[] args) throws Exception {
ChannelFactory factory =
new NioServerSocketChannelFactory(
Executors.newCachedThreadPool(),
Executors.newCachedThreadPool());
ServerBootstrap bootstrap = new ServerBootstrap(factory);
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
public ChannelPipeline getPipeline() {
return Channels.pipeline(new TimeDecoder(),new DiscardServerHandler());//此处注意是否有顺序要求
}
});
bootstrap.setOption("child.tcpNoDelay", true);
bootstrap.setOption("child.keepAlive", true);
bootstrap.bind(new InetSocketAddress(8080));
}
}
服务器资源释放包括:释放socket相关资源、释放ChannelFactory占用的资源
Netty提供了ChannelGroup来管理所有活动的连接,如果连接关闭则自动从集合中删除。
public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) {
TimeServer.allChannels.add(e.getChannel());(34)
}
public class TimeServer {
static final ChannelGroup allChannels = new DefaultChannelGroup("time-server"(35));
public static void main(String[] args) throws Exception {
...
ChannelFactory factory = ...;
ServerBootstrap bootstrap = ...;
...
Channel channel(36) = bootstrap.bind(...);
allChannels.add(channel);(37)
waitForShutdownCommand();(38)
ChannelGroupFuture future = allChannels.close();(39)
future.awaitUninterruptibly();
factory.releaseExternalResources();
}
}
客户端:
public class TimeClient {
public static void main(String[] args) throws Exception {
String host = args[0];
int port = Integer.parseInt(args[1]);
ChannelFactory factory =
new NioClientSocketChannelFactory(
Executors.newCachedThreadPool(),
Executors.newCachedThreadPool());
ClientBootstrap bootstrap = new ClientBootstrap(16)(factory);
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
public ChannelPipeline getPipeline() {
return Channels.pipeline(new TimeDecoder(),new TimeClientHandler());//此处注意是否有顺序要求
}
});
bootstrap.setOption("tcpNoDelay"(17), true);
bootstrap.setOption("keepAlive", true);
ChannelFuture future= bootstrap.connect(18)(new InetSocketAddress(host, port));
future.awaitUninterruptibly();(30)
if (!future.isSuccess()) {
future.getCause().printStackTrace();(31)
}
future.getChannel().getCloseFuture().awaitUninterruptibly();(32)
factory.releaseExternalResources();(33)
}
}
}
参考文献:
http://netty.io/3.6/guide/
分享到:
相关推荐
netty 3.6 的jar包给需要的人
这是一个http server ,可以接受get post 请求,根据需求查询数据库并返回数据。完整的server代码,无client代码
netty最新正式发布版3.6.3的api文档,英文原版,作成chm格式,方便检索。
本demo紧密结合了本人发布的《初识Netty》一文中的示例,为学习者提供了一个直观、实用的学习参考。项目中,你可以清晰地看到BIO与NIO模型在Netty中的灵活运用,如何通过Netty的高性能特性来优化网络通信。此外,...
springboot整合 netty做心跳检测 springboot整合 netty做心跳检测 springboot整合 netty做心跳检测 springboot整合 netty做心跳检测 springboot整合 netty做心跳检测 springboot整合 netty做心跳检测 springboot整合...
Netty基础,用于学习Netty,参考黑马程序员的netty教程
slf4fx-netty-服务器SLF4Fx 服务器使用 Netty 而不是 Apache Mina。...变化0.6.0 此版本仅与 Netty 4 兼容(之前仅与 Netty 3.6 兼容) 将包名更改为 io.github.lkowalczyk 要求: JDK 1.5 或更新版本网状 3.6.6
Netty (netty-netty-4.0.56.Final.tar.gz)是一个 NIO 客户端服务器框架,可以快速轻松地开发协议服务器和客户端等网络应用程序。它极大地简化和流线了网络编程,例如 TCP 和 UDP 套接字服务器。 “快速和简单”并...
netty-buffer-4.1.32.Final-sources.jar netty-buffer-4.1.32.Final.jar netty-build-22-sources.jar netty-build-22.jar netty-codec-4.1.32.Final-sources.jar netty-codec-4.1.32.Final.jar netty-codec-...
Netty (netty-netty-5.0.0.Alpha2.tar.gz)是一个 NIO 客户端服务器框架,可以快速轻松地开发协议服务器和客户端等网络应用程序。它极大地简化和流线了网络编程,例如 TCP 和 UDP 套接字服务器。 “快速和简单”并...
Netty (netty-netty-3.10.6.Final.tar.gz)是一个 NIO 客户端服务器框架,可以快速轻松地开发协议服务器和客户端等网络应用程序。它极大地简化和流线了网络编程,例如 TCP 和 UDP 套接字服务器。 “快速和简单”并...
跟闪电侠学Netty:Netty即时聊天实战与底层原理-book-netty
netty-3.2.5.Final.jar netty包
Netty入门教程
Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty is a NIO client server framework which ...
Netty进阶之路,跟着案例学Netty,李林峰大神新作。值得一读。
《Netty进阶之路:跟着案例学Netty》中的案例涵盖了Netty的启动和停止、内存、并发多线程、性能、可靠性、安全等方面,囊括了Netty绝大多数常用的功能及容易让人犯错的地方。在案例的分析过程中,还穿插讲解了Netty...
本jar包为最新的netty-all-4.1.29c.jar 可导入直接用 Netty 是一个利用 Java 的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的 API 的客户端/服务器框架。 Netty 是一个广泛使用的 Java 网络编程框架...
springboot +netty+activeMq在线客服系统springboot +netty+activeMq在线客服系统springboot +netty+activeMq在线客服系统springboot +netty+activeMq在线客服系统springboot +netty+activeMq在线客服系统springboot...
Netty 是一个利用 Java 的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的 API 的客户端/服务器框架。 Netty 是一个广泛使用的 Java 网络编程框架(Netty 在 2011 年获得了Duke's Choice Award,见...