后端使用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.
|