flutter 下 protobuf 编解码的问题,卡好几天。

2021-10-28 18:03:02 +08:00
 keppelfei

后端使用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();
      });
    });

在最后监听的方法中没有做粘包、解包处理动作,所以有时候能收到消息,有时候收不到。主要是不懂怎么处理这个消息头长度的问题,希望有大佬指点一下。

1362 次点击
所在节点    Flutter
5 条回复
bg7lgb
2021-10-28 23:36:26 +08:00
tcp 会存在粘包的问题,需要自己做分包处理。
可以做一个缓冲区,把数据接收下来,解析,足够一个包了,拿出来处理。

以前用 C 、C++都是这样做的,现在语言越来越高级,都很少直接处理 socket 了。
keppelfei
2021-10-29 08:54:10 +08:00
@bg7lgb 我发消息是用 http 发送的,怎么知道这个包的头部组成呢?
Chan66
2021-10-29 16:13:23 +08:00
通过帧头帧尾来判断吧
bg7lgb
2021-10-30 10:21:54 +08:00
已经上 http 协议了,那就按 HTTP 来解码了。HTTP 可没包大小的概念。先解析头,再解析 BODY.
keppelfei
2021-11-01 09:13:56 +08:00
@Chan66 有没有详细的流程解说,新手不太明白,或者说从哪个方向入手

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/811328

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX