
后端使用netty+protobuf 协议通过暴露 socket 端口,客户端进行 socket 连接
服务端编解码器如下:
public class SocketServerInitializer extends ChannelInitializer<Channel> { @Override protected void initChannel(Channel ch) throws Exception { // 31 秒没有向客户端发送消息就发生心跳 ch.pipeline().addLast(new IdleStateHandler(31, 0, 0)) // google Protobuf 编解码 .addLast(new ProtobufVarint32FrameDecoder()) .addLast(new ProtobufDecoder(WSBaseReqProtoOuterClass.WSBaseReqProto.getDefaultInstance())) .addLast(new ProtobufVarint32LengthFieldPrepender()) .addLast(new ProtobufEncoder()) .addLast(new SocketServerHandler()); } } 客户端使用 flutter 编写:
await Socket.connect('172.16.0.193', 9002).then((socket) { cOnnectFlag= true; update(); /// 创建连接鉴权 socket.add(buildWSBaseReqProto(1, info.sid, info.uid)); /// 开始维持心跳, 每 30s 进行一次心跳连接 Timer.periodic(Duration(seconds: 30), (timer) { socket.add(buildWSBaseReqProto(0, info.sid, info.uid)); }); int HeaderLength = 2 /// 开始监听 socket 记录 socket.listen((event) { WSBaseResProto res = WSBaseResProto.fromBuffer(event.sublist(HeaderLength, event.length)); msgList.add(res); update(); }); }); 在最后监听的方法中没有做粘包、解包处理动作,所以有时候能收到消息,有时候收不到。主要是不懂怎么处理这个消息头长度的问题,希望有大佬指点一下。
1 bg7lgb 2021-10-28 23:36:26 +08:00 tcp 会存在粘包的问题,需要自己做分包处理。 可以做一个缓冲区,把数据接收下来,解析,足够一个包了,拿出来处理。 以前用 C 、C++都是这样做的,现在语言越来越高级,都很少直接处理 socket 了。 |
3 Chan66 2021-10-29 16:13:23 +08:00 通过帧头帧尾来判断吧 |
4 bg7lgb 2021-10-30 10:21:54 +08:00 已经上 http 协议了,那就按 HTTP 来解码了。HTTP 可没包大小的概念。先解析头,再解析 BODY. |