Open xiwenAndlejian opened 5 years ago
Netty
提供了EmbeddedChannel
类,方便我们对ChannelHandler
进行测试。
例如,对上述解码器进行测试
@Test
public void testChannel() {
// 消息
RpcRequestPacket in = RpcRequestPacket.builder()
.clazz(Hello.class)
.methodName("hello")
.parameters(null)
.build();
EmbeddedChannel channel = new EmbeddedChannel(
new RpcFrameDecoder(),
new PacketEncoder(),
new PacketDecoder()
);
// 写入入站消息
Assert.assertTrue(channel.writeInbound(in));
Assert.assertTrue(channel.writeInbound(in));
// 读取消息,并判断消息是否成功解析
RpcRequestPacket read = channel.readInbound();
Assert.assertEquals(in, read);
read = channel.readInbound();
Assert.assertEquals(in, read);
}
Rpc 实现笔记(三)半包粘包 & 使用 EmbeddedChannel 进行单元测试
半包粘包现象
具体现象
服务端与客户端建立连接后,发送
1000
次hello
,服务端将接受的结果打印到终端。一下是部分服务端接受结果:
根据输出我们可以看出存在三种接受情况
hello
,数据的正常接受情况o
hellohellohello
、hellohello
等这里暂不讨论出现上述
粘包
、半包
现象的具体原理,仅给出解决方案。Netty 解码器
Netty
内部提供了解决上述现象的一些解码器。例如:
固定长度解码器:FixedLengthFrameDecoder
行解码器:LineBasedFrameDecoder
分隔符解码器:DelimiterBasedFrameDecoder
长度域解码器:LengthFieldBasedFrameDecoder
具体选择哪一个解码器,需要根据 TCP 传输时使用的协议格式而定。这里我选择的是
LengthFieldBasedFrameDecoder
。使用的协议格式如下:魔法数[4]-版本号[1]-数据长度[4]-序列化方式[1]-消息类型长度[4]-消息类型[N]-消息长度[4]-消息-[M]
代码