Flutter上线项目实战——即时通讯Protobuf

2021-05-27  本文已影响0人  callme大帅

一、应用背景:

Protobuf是google 的一种数据交换的格式,它独立于语言,独立于平台。

优点:

缺点:

在一个需要大量的数据传输的场景中,如果数据量很大,那么选择protobuf可以明显的减少数据量,减少网络IO,从而减少网络传输所消耗的时间。考虑到作为一个主打社交的产品,消息数据量会非常大,同时为了节约流量,所以采用protobuf是一个不错的选择。

二、使用

1.引入protobuf库

pubspec.yaml

...

protobuf: 1.0.1

2.编写proto文件

socket.message.proto

syntax = "proto3";
package socket;

// 发送聊天信息
message Message {
  string eventId = 1;
  string from = 2;
  string to = 3;
  string createAt = 4;
  string type = 5;
  string body = 6;
}

// 收到聊天消息
message AckMessage {
  string eventId = 1;
}

3.生成proto相关Model

Terminal

protoc --dart_out=. socket.message.proto

4.编码、发消息

a.准备protobuf对象

Message message = Message();
message.eventId = '####';
message.type = 'text';
message.body = 'hello world';

b.ProtobufUtil编码

const MESSAGE_HEADER_LEN = 2;
/// 数据编码
static List<int> encode(int type, var content) {
    ByteData data = ByteData(MESSAGE_HEADER_LEN);
    data.setUint16(0, type, Endian.little);
    List<int> msg = data.buffer.asUint8List() + content.writeToBuffer().buffer.asUint8List();
    return msg;
}

c.发消息

/// 发送
sendSocket(int type, var content) async {
    IOWebSocketChannel channel = await SocketService.getInstance().getChannel();
    if (channel == null) return;
    List<int> msg = ProtobufUtil.encode(type, content);
    channel.sink.add(msg);
}

sendSocket(11, message)

5.收消息、解码

a.解码

  /// 数据解码
  static DecodedMsg decode(data) {
    Int8List int8Data = Int8List.fromList(data);
    Int8List contentTypeInt8Data = int8Data.sublist(0, MESSAGE_HEADER_LEN);
    Int8List contentInt8Data = int8Data.sublist(MESSAGE_HEADER_LEN, int8Data.length);
    int contentType = contentTypeInt8Data.elementAt(0);


    GeneratedMessage content;
    switch (contentType) {
      case 10:
        content = AckMessage.fromBuffer(contentInt8Data);
        break;
      case 11:
        content = Message.fromBuffer(contentInt8Data);
        break;
    }

    DecodedMsg decodedMsg;
    if (contentType != null && content != null) {
      decodedMsg = DecodedMsg(
        contentType: contentType,
        content: content,
      );
    }
    return decodedMsg;
  }
  

b.收消息

  channel.stream.listen((data) {
    DecodedMsg msg = ProtobufUtil.decode(data);
  }


完结,撒花🎉

上一篇下一篇

猜你喜欢

热点阅读