同样的提供了一个接口向服务端发送消息,当服务端收到了一个特殊指令时也会向客户端返回内容:
@Override protected void channelRead0(ChannelHandlerContext ctx, BaseRequestProto.RequestProtocol msg) throws Exception { LOGGER.info("收到msg={}", msg.getReqMsg()); if (999 == msg.getRequestId()){ BaseResponseProto.ResponseProtocol responseProtocol = BaseResponseProto.ResponseProtocol.newBuilder() .setResponseId(1000) .setResMsg("服务端响应") .build(); ctx.writeAndFlush(responseProtocol) ; } }在 swagger 中调用相关接口:
在日志可以看到服务端收到了消息,同时客户端也收到了返回:
虽说 Netty 封装了 Google Protobuf 相关的编解码工具,其实查看它的编码工具就会发现也是利用上文提到的 api 实现的。
Protocol 拆、粘包Google Protocol 的使用确实非常简单,但还是有值的注意的地方,比如它依然会有拆、粘包问题。
不妨模拟一下:
连续发送 100 次消息看服务端收到的怎么样:
会发现服务端在解码的时候报错,其实就是被拆、粘包了。
这点 Netty 自然也考虑到了,所以已经提供了相关的工具。
//拆包解码 .addLast(new ProtobufVarint32FrameDecoder()) .addLast(new ProtobufVarint32LengthFieldPrepender())只需要在服务端和客户端加上这两个编解码工具即可,再来发送一百次试试。
查看日志发现没有出现一次异常,100 条信息全部都接收到了。
这个编解码工具可以简单理解为是在消息体中加了一个 32 位长度的整形字段,用于表明当前消息长度。
总结网络这块同样是计算机的基础,由于近期在做相关的工作所以接触的比较多,也算是给大学补课了。
后面会接着更新 Netty 相关的内容,最后会产出一个高性能的 HTTP 以及 RPC 框架,敬请期待。