01 引言
我们做了Websocket的案例,并没有像TCP协议一样处理拆包和粘包问题。Websocket基于Frame已经自动帮我们解决了拆包和粘包问题,我们一起来看看是怎么解决的!
02 WebSocketFrame
WebSocketFrame是 Netty 中用于表示WebSocket协议数据帧的抽象基类。在WebSocket通信中,所有数据(文本、二进制、控制帧等)都通过帧的形式进行传输。
核心属性
// 帧的最终标志位(FIN)privatefinalbooleanfinalFragment;// 保留位(RSV1, RSV2, RSV3)privatefinalintrsv;finalFragment参数是解决拆包粘包的关键标志位。
03 处理流程
3.1 调用链
3.2 解码关键类
io.netty.handler.codec.http.websocketx.WebSocket08FrameDecoder
WebSocket协议定义了明确的帧格式,每个帧都有明确的边界标识:
关键字段:
- FIN位(1位):标识是否是消息的最后一个帧
- opcode(4位):操作码,标识帧类型(文本、二进制、控制帧等)
- MASK位(1位):标识是否掩码
- Payload length(7位):负载长度,自动扩展
而WebSocket08FrameDecoder专门定义了解析帧的字段。
其中关键的代码块:
byteb=in.readByte();frameFinalFlag=(b&0x80)!=0;(b & 0x80) != 0是用于检测某个字节 b 的最高位(即第7位,从右往左数)是否为1。如果为1,则返回true,表示数据已经读完。这里正是解决拆包粘包的关键标志位。
3.3 整个解析流程
- 长度字段解析:首先读取帧头部,解析payload长度
- 动态读取:根据长度字段值,读取相应字节数的数据
- 帧完整性检查:检查FIN位,确定消息是否结束
- 消息聚合:对于分片消息(FIN=0),自动缓存和重组
04 小结
WebSocket的拆包粘包问题已经妥善解决,开发者只需要配置WebSocketServerProtocolHandler,Netty就会在合适的时机自动创建和配置WebSocket13FrameDecoder。为我们解决困扰,无需手动处理。