开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第26天,点击查看活动详情
LoginUtil 用于设置登录标志位以及判断是否有标志位,如果有标志位,不管标志位的值是什么,都表示已经成功登录过
控制台输入消息并发送
可以自己吃透
pipeline 与 channelHandler
Netty 中的 pipeline 和 channelHandler用来解决代码臃肿,通过责任链设计模式来组织代码逻辑,并且能够支持逻辑的动态添加和删除
pipeline 与 channelHandler 的构成
实战:构建客户端与服务端 pipeline
我们前面实现的decode方法可以直接继承ByteToMessageDecoder并实现里面的decode方法即可
- 基于 ByteToMessageDecoder,我们可以实现自定义解码,而不用关心 ByteBuf 的强转和 解码结果的传递。
- 基于 SimpleChannelInboundHandler,我们可以实现每一种指令的处理,不再需要强转,不再有冗长乏味的
if else逻辑,不需要手动传递对象。 - 基于
MessageToByteEncoder,我们可以实现自定义编码,而不用关心 ByteBuf 的创建,不用每次向对端写 Java 对象都进行一次编码。
实战:拆包粘包理论与解决方案
当我们使用for循环进行发送消息时,会出现有些消息不完整的情况,这种就叫粘包半包
为什么会出现呢?
因为Netty底层还是实现的TCP协议,TCP协议本来就有这种缺陷,因此使用拆包解决问题
但是在没有使用Netty使用拆包将会十分麻烦,而Netty天生就有一些拆包器来支持拆包
基于长度域拆包器
new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 7, 4);
Server
需要加上ch.pipeline().addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 7, 4)); 才能使基于长度拆包器生效,
Client
同样的,客户端也需要添加ch.pipeline().addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 7, 4));才能解决粘包半包问题。
通过以上分析,我们发现这样添加会有些繁琐,因此后续我们会将他们其中的一部分进行合并。