V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
keppelfei
V2EX  ›  Flutter

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

  •  
  •   keppelfei · 2021-10-28 18:03:02 +08:00 · 1312 次点击
    这是一个创建于 883 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

    以前用 C 、C++都是这样做的,现在语言越来越高级,都很少直接处理 socket 了。
    keppelfei
        2
    keppelfei  
    OP
       2021-10-29 08:54:10 +08:00
    @bg7lgb 我发消息是用 http 发送的,怎么知道这个包的头部组成呢?
    Chan66
        3
    Chan66  
       2021-10-29 16:13:23 +08:00
    通过帧头帧尾来判断吧
    bg7lgb
        4
    bg7lgb  
       2021-10-30 10:21:54 +08:00
    已经上 http 协议了,那就按 HTTP 来解码了。HTTP 可没包大小的概念。先解析头,再解析 BODY.
    keppelfei
        5
    keppelfei  
    OP
       2021-11-01 09:13:56 +08:00
    @Chan66 有没有详细的流程解说,新手不太明白,或者说从哪个方向入手
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3372 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 10:42 · PVG 18:42 · LAX 03:42 · JFK 06:42
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.