Channel是客户端和服务端建立的一个连接通道,是Netty抽象出来的网络I/O读写相关的接口;客户端有一个Channel(SocketChannel),服务端也有一个Channel(NioSocketChannel),当客户端和服务端建立连接后,客户端的Channel会跟服务端的Channel进行联通;
ChannelHandler是负责Channel的逻辑处理;
ChannelPipeline负责管理ChannelHandler的容器,它的存储结构为双向链表;
一个Channel包含一个ChannelPipeline,所有ChannelHandler都会顺序加入到ChannelPipeline中,创建Channel时会自动创建一个ChannelPipeline;每个Channel都有一个管理它的ChannelPipeline,这个关联关系是永久性的;
io.netty.channel.AbstractChannel
io.netty.channel.ChannelPipeline 接口都有往ChannelPipline添加ChannelHandler的addXXX方法;
而ChannelPipeline 中又维护了一个由ChannelHandlerContext 组成的双向链表,并且每个 ChannelHandlerContext 中又关联着一个 ChannelHandler;
head为ChannelHandlerContext组成的双向链表的前驱指针,tail为ChannelHandlerContext组成的双向链表的后继指针;
AbstractChannelHandlerContext为抽象类,最终它的实现类为io.netty.channel.DefaultChannelHandlerContext;
io.netty.channel.DefaultChannelHandlerContext
当这些状态发生改变时,将会生成对应的事件;这些事件将会被转发给 ChannelPipeline 中的 ChannelHandler,其可以随后对它们做出响应;
测试demo如下:
public class EchoServerHandler extends ChannelInboundHandlerAdapter { private final static Logger logger = LoggerFactory.getLogger(EchoServerHandler.class); @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { ByteBuf data = (ByteBuf) msg; logger.info("服务端收到数据: "+ data.toString(CharsetUtil.UTF_8)); ctx.writeAndFlush(data); } @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { logger.info("EchoServerHandle channelReadComplete..."); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); ctx.close(); } /** * Channel已创建,但未注册到EventLoop * @param ctx * @throws Exception */ @Override public void channelRegistered(ChannelHandlerContext ctx) throws Exception { logger.info("EchoServerHandle channelRegistered..."); } /** * Channel注册到EventLoop * @param ctx * @throws Exception */ @Override public void channelUnregistered(ChannelHandlerContext ctx) throws Exception { logger.info("EchoServerHandle channelUnregistered..."); } /** * 当客户端连接服务器完成就会触发该方法 * @param ctx * @throws Exception */ @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { logger.info("EchoServerHandle channelActive..."); } /** * 客户端下线 * @param ctx * @throws Exception */ @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { logger.info("EchoServerHandle channelInactive..."); } }
参考:《Netty实战》
原文:https://www.cnblogs.com/coder-zyc/p/14383728.html