Netty WebSocket 拆包浅析
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Netty WebSocket 拆包浅析相关的知识,希望对你有一定的参考价值。
参考技术A 最近项目中运用 WebSocket 的场景越来越多,自然而然。踩到的坑也就越来越多,例如最经常遇到的拆包,粘包问题。而当发现这个问题的时候,起初我认为与我之前通过 mina 实现自定义协议头,解决 socket 进行数据传输时遇到拆包问题的场景是一样的。而当我慢慢深入了解 WebSocket的时候才发现,实际上,WebSocket 的出现,就是为了解决拆包,粘包的问题的。因为这些事情,本身就是应该由运用层去解决,而不是在TCP/IP层解决。通过网络搜索,我们可以知道 WebSocket 协议是根据 RFC6455 规范实现的,而最新版本是13(距离现今也接近10年了)。
以下是 WebScoket 定义的协议帧片段。
通过以上的帧定义片段。我也就明白了,为什么说 WebSocket 是为了解决拆包,粘包问题等一系列应用层问题而诞生的。从 RCF6455 规范定义第 5.3 章节中可以发现,每次发送或者接收的帧报文中,都会有定义协议的一些信息,例如头部大小,数据大小,以及帧类型,标识位等信息。
看完协议定义,那么开始查看 Netty 源码。
以下是 Netty 定义的相关帧类型以供开发者使用。
当服务端接收到协议由 HTTP 握手升级协议 WebSocket 时,我们需要通过 WebSocketServerHandshakerFactory 类新建 WebSocketHandshaker ,此时会判断 WebSocket 协议版本以及相关信息进行校验。
而 WebSocketServerHandshaker 中,分别定义了 WebSocketFrameDecoder , WebSocketFrameEncoder 进行解码,编码调用。
那么从现实开始,大概也就清楚了, Netty 中 WebSocket 和 Socket 实现,实际上都是一样的,都是一个解码器(负责接收数据,处理成需要的类型,例如文本,二进制),一个编码器(负责根据协议版本,进行帧封装)的结构。
从 WebSocket13FrameDecoder 我们可以得知,实际上 WebSocket13FrameDecoder 是继承自 WebSocket08FrameDecoder (由于实现细节一致),而 WebSocket08FrameDecoder 是继承自 ByteToMessageDecoder ,实际上都是通过二进制数据进行解码处理的。
查看 WebSocket08FrameDecoder 我们可以了解到具体的实现细节,就是每次解码的时候,都会读取首部信息,然后依次对数据进行处理。而拆包等操作,都是已经进行的相应处理和封装。
看完 Netty 的源码实现,那么就可以进行实际的编码解决问题了。
当服务端/客户端发现包文过大时,会进行拆包。而为每个包定义一系列的定义。
例如:当接收一个 Text 消息时, Netty 首先会实例化一个 TextWebSocketFrame 对象并传递给调用方,而通过 isFinalFragment 我们可以判断出,这个帧对象是否已经传输完毕,如果传输完毕,那么进行业务处理。如果没有传输完毕,那么继续等待余下信息,进行拼接处理。
以上为服务端接收拆包信息的处理方式,反之亦然,客户端接收消息也可以进行相应操作。而根据 WebSocket 1.3 版本实现的组件,也都根据 RFC6455 规范进行相应实现,可以实现无缝对接。
参考: Netty做webSocket客户端,服务端拆包发送客户端接收处理
面试官:什么是Netty粘包拆包?怎么解决Netty粘包拆包问题
哈喽!大家好,我是小奇,一位热爱分享的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新 一、前言 书接上回,昨天肯定是狗蛋通风报信,导致大爷们那么神秘的下象棋基地也被大妈捣毁了,今天肯定去下不了象棋了。 那我今天趁着天气好去地里
以上是关于Netty WebSocket 拆包浅析的主要内容,如果未能解决你的问题,请参考以下文章