json 模型
{
"event": "message",
"data": {
"type": "text",
"content": "",
"from": ""
}
}
event`类型:`message/name/name_ack/broadcast/error/keepalive
Flutter 客户端
-
Flutter中用于websocket 访问的库
-
为 websocket 添加心跳机制
-
使用 protobuf 改造案例
全称是Google Protocol Buffer,是一种高效轻便的结构化数据存储方式,可用于(数据)通信协议、数据存储等。它与语言无关,平台无关,且高效性能好。
Protobuf 语法简介
Protobuf 使用.proto文件来定义消息,一个简单示例如下
// 语法版本
syntax = "proto3";
message SearchRequest {
string query = 1;
int32 page = 2;
int32 result = 3;
}
整体看起来和Dart中的类声明相似,message后面指定的名称,会映射成Dart的类名。消息定义中的每个字段都有一个唯一的数字 ,这是字段编号,这些字段编号用于以消息二进制格式标识字段,一旦消息类型被使用,就不应该更改这些字段。
消息嵌套
syntax = "proto3";
message SearchRequest {
string query = 1;
int32 page = 2;
// 声明Result类型消息
message Result {
string url = 1;
string title = 2;
}
// 在SearchRequest中定义一个Result字段
Result result = 3;
}
这些消息中还能定义枚举。枚举的第一个常量编号映射到零,意即必须有一个字段编号为0的值
syntax = "proto3";
message SearchRequest {
string query = 1;
int32 page = 2;
int32 result = 3;
// 使用snippets修改,声明列表,此处为字符串列表
repeated string snippets = 3;
// 声明一个枚举类型
enum Corpus {
UNIVERSAL = 0;
WEB = 1;
IMAGES = 2;
LOCAL = 3;
}
// 在SearchRequest中定义一个枚举字段
Corpus corpus = 4;
}
在Dart 中的使用
-
下载protobuf 工具
-
安装dart语言的protoc插件
pub global activate protoc_plugin安装插件后,需要将该插件路径配置到PATH环境变量中,Windows下是
%APPDATA%\Pub\Cache\bin,Mac 或 Linux系统下是$HOME/.pub-cache/bin -
将
.proto文件编译成dart文件protoc --dart_out=. test.proto将生成的带pb的dart文件拷贝到项目中
-
项目中引入protobuf 依赖
dependencies: protobuf: ^1.0.1
附录:字段类型对应表
| .proto | Notes | Java | Python[2] | Go | Dart |
|---|---|---|---|---|---|
| double | double | float | float64 | double | |
| float | float | float | float32 | double | |
| int32 | 使用可变长度编码。编码负数效率低,如果您的字段可能具有负值,请改用sint32。 | int | int | int32 | int |
| int64 | 使用可变长度编码。负数编码效率低下,如果您的字段可能具有负值,请改用sint64。 | long | int/long[3] | int64 | Int64 |
| uint32 | 使用可变长度编码。 | int[1] | int/long[3] | uint32 | int |
| uint64 | 使用可变长度编码。 | long[1] | int/long[3] | uint64 | Int64 |
| sint32 | 使用可变长度编码。有符号的int值。这些比普通的int32更有效地编码负数。 | int | int | int32 | int |
| sint64 | 使用可变长度编码。有符号的int值。这些比普通的int64更有效地编码负数。 | long | int/long[3] | int64 | Int64 |
| fixed32 | 始终为四个字节。如果值通常大于228,则比uint32更有效。 | int[1] | int/long[3] | uint32 | int |
| fixed64 | 始终为八个字节。如果值通常大于256,则比uint64更有效。 | long[1] | int/long[3] | uint64 | Int64 |
| sfixed32 | 始终为四个字节。 | int | int | int32 | int |
| sfixed64 | 始终为八个字节。 | long | int/long[3] | int64 | Int64 |
| bool | boolean | bool | bool | bool | |
| string | 字符串必须始终包含UTF-8编码或7位ASCII文本,并且不能超过232。 | String | str/unicode[4] | string | String |
| bytes | 可以包含不超过232个任意字节序列。 | ByteString | str | []byte | List |
[1]在Java中,无符号的32位和64位整数使用带符号的对等体表示,最高位仅存储在符号位中。
[2]在所有情况下,对字段设置值都会进行类型检查以确保其有效。
[3]64位或无符号32位整数在解码时始终表示为long,但是如果在设置字段时给出了int,则可以为int。 在所有情况下,该值都必须适合设置时表示的类型。 参见[2]。
[4]Python字符串在解码时表示为unicode,但如果给出了ASCII字符串,则可以为str(此字符串可能会发生变化)。