服务端的创建时序图:
步骤:
1.创建ServerBootstrap实例
2.设置并绑定Reactor线程池
3.设置并绑定服务端channel
4.TCP链路建立,创建并初始化ChannelPipeline
5.初始化ChannelPipeline完成以后,添加并设置ChannelHandler
6.绑定监听端口并启动服务端
7.Selector轮询,由Reactor线程NioEventLoop负责调度和执行Selector轮询操作,选择准备就绪的channel集合
8.当轮询到准备就绪的channel之后,就由Reactor线程NioEventLoop执行ChannelPipeline的相应方法,最终调度并执行ChannelHandler
9.执行netty默认的channelHandler,和用户自定义的channelHandler
代码示例:
public void bind(int port){
//配置服务端的NIO线程 Reactor线程组
//负责服务端接收客户端的连接
EventLoopGroup bossGroup = new NioEventLoopGroup();
//负责进行SocketChannel的网络读写
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
//辅助启动类
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
//设置channel类型为NioServerSocketChannel 类似于JDK中ServerSocketChannel
.channel(NioServerSocketChannel.class)
//配置TCP参数
.option(ChannelOption.SO_BACKLOG, 1024)
//绑定I/O事件的处理类 类似于Reactor模式中的handler
.childHandler(new ChildChannelHandler());
//绑定端口 同步等待成功
ChannelFuture f = b.bind(port).sync();
//等待服务端监听端口关闭
f.channel().closeFuture().sync();
} catch (Exception e) {
// TODO: handle exception
} finally {
//释放资源
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
客户端时序图:
步骤:
1.用户线程创建Bootstrap实例
2.创建处理客户端连接,I/O读写Reactor线程组NioEventLoopGroup
3.创建NioSocketChannel
4.创建默认的ChannelHandlerPipeline,用户调度和执行网络事件
5.异步发起TCP连接,如果成功将NioSocketChannel注册到多路复用选择器上,监听读操作位,用于数据读取和消息发送,如果失败,注册连接操作位到多路复用选择 器,等待连接结果
6.注册对应的网络监听状态位到多路复用选择器
7.由多路复用选择器轮询Channel,处理连接结果
8.如果连接成功,设置Future结果,发送连接成功事件,触发ChannelHandlerPipeline执行
9.由ChannelHandlerPipeline调度和执行系统和用户ChannelHandler
示例代码:
public void connect(int port,String host){
//客户端的NIO线程组
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY, true)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel channel) throws Exception {
// TODO Auto-generated method stub
//以换行符作为消息结束标志
channel.pipeline().addLast(new LineBasedFrameDecoder(1024));
//将消息转换为String
channel.pipeline().addLast(new StringDecoder());
channel.pipeline().addLast(new TimeClientHandler());
}
});
//发起异步连接操作
ChannelFuture f = b.connect(host, port).sync();
//等待客户端链路关闭
f.channel().closeFuture().sync();
} catch (Exception e) {
// TODO: handle exception
} finally {
//释放资源
group.shutdownGracefully();
}
}