Netty实战 IM即时通讯系统(十二)构建客户端与服务端pipeline
零、 目录
- IM系统简介
- Netty 简介
- Netty 环境配置
- 服务端启动流程
- 客户端启动流程
- 实战: 客户端和服务端双向通信
- 数据传输载体ByteBuf介绍
- 客户端与服务端通信协议编解码
- 实现客户端登录
- 实现客户端与服务端收发消息
- pipeline与channelHandler
- 构建客户端与服务端pipeline
- 拆包粘包理论与解决方案
- channelHandler的生命周期
- 使用channelHandler的热插拔实现客户端身份校验
- 客户端互聊原理与实现
- 群聊的发起与通知
- 群聊的成员管理(加入与退出,获取成员列表)
- 群聊消息的收发及Netty性能优化
- 心跳与空闲检测
- 总结
- 扩展
一、 ChannelInboundHandlerAdapter 与 ChannelOutboundHandlerAdapter
-
首先是ChannelInboundHandlerAdapter , 这个适配器只用用于实现其接口ChannelInboundHandler 的所有方法,这样我们在编写自己的handler时就不需要实现handler里的每一个方法,而只需要实现我们关心的方法 , 默认情况下 , 对于ChannelInboundHandlerAdapter , 我们比较关心的是他的channelRead()
ChannelInboundHandlerAdapter.java @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { ctx.fireChannelRead(msg); }
- 他的作用就是接受上一个handler的输出 , 这里的msg 就是上一个handler的输出 。 大家也可以看出 , 默认情况下adapter会通过fireChannelRead() 方法直接把本handler的处理结果传递给下一个handler 。
-
与ChannelinboundHandlerAdapter相似的是ChannelOutboundHandlerAdapter , 他的核心方法是 write() 方法
ChannelOutboundHandlerAdapter.java @Override public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { ctx.write(msg, promise); }
- 默认情况下 , 这个adapter也会把对象传递给下一个outbound节点 , 需要注意的是他的传播顺序与inbound相反 。
-
我们往pipeline中添加的第一个handler中的channelRead方法中 , msg对象其实就是ByteBuf , 服务端在接收数据之后 , 应该首先把这个ByteBuf解码 , 然后把解码之后的结果传递给下一个handler :
@Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { ByteBuf requestByteBuf = (ByteBuf) msg; // 解码 Packet packet = PacketCodeC.INSTANCE.decode(requestByteBuf); // 解码后的对象传递到下一个 handler 处理 ctx.fireChannelRead(packet) }
-
在开始解码之前我们来了解另外一个特殊的handler
</