后端使用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();
});
});
在最后监听的方法中没有做粘包、解包处理动作,所以有时候能收到消息,有时候收不到。主要是不懂怎么处理这个消息头长度的问题,希望有大佬指点一下。
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.