小程序websocket开发指南( 二 )


名词解释
Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化 。它很适合做数据存储或 RPC 数据交换格式 。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式 。
基本原理
一般情况下,采用静态编译模式,先写好 .proto 文件,再用 Protobuf 编译器生成目标语言所需要的源代码文件,将这些生成的代码和应用程序一起编译 。
读写数据过程是将对象序列化后生成二进制数据流,写入一个 fstream 流,从一个 fstream 流中读取信息并反序列化 。
优缺点

  • 优点
Protocol Buffers 在序列化数据方面,它是灵活的,高效的 。相比于 XML 来说,Protocol Buffers 更加小巧,更加快速,更加简单 。一旦定义了要处理的数据的数据结构之后,就可以利用 Protocol Buffers 的代码生成工具生成相关的代码 。甚至可以在无需重新部署程序的情况下更新数据结构 。只需使用 Protobuf 对数据结构进行一次描述,即可利用各种不同语言或从各种不同数据流中对你的结构化数据轻松读写 。
Protocol Buffers 很适合做数据存储或 RPC 数据交换格式 。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式 。
  • 缺点
消息结构可读性不高,序列化后的字节序列为二进制序列不能简单的分析有效性;
字节消息通道(Frontier)系统整体设计
为了维护用户在线状态,需要和服务端保持长连接,决定采用websocket来跟服务端进行通信,同时使用消息通道系统来转发消息 。
时序图
小程序websocket开发指南

文章插图
 
技术要点
交互协议
  • connectSocket:创建一个WebSocket连接实例,并通过返回的?socketTask?操作该连接 。
const wsUrl = `${domain}/ws/v2?aid=2493&device_id=${did}&fpid=100&access_key=${access_key}&code=${code}`let socketTask = tt.connectSocket({    url: wsUrl,    protocols: ['p1']});
  • ?wsUrl?遵循?Frontier?的交互协议:
  • aid:应用id,不是宿主App的appid,由服务端指定
  • fpid:由服务端指定
  • device_id:设备id,服务端通过aid+userid+did来维护长连接
  • access_key:用于防止攻击,一般用md5加密算法生成(?md5.hexMD5(fpid + appkey + did + salt);?)
  • code:调用?tt.login?获取的code,服务端通过 code2Session 可以将其转化为open_id,然后进一步转化为user_id用于标识用户的唯一性 。
  • note:由于code具有时效性,每次重新建立?websocket?连接时,需要调用?tt.login?重新获取code 。
数据协议
前面介绍了那么多关于?Protobuf?的内容,小程序的?webSocket?接口发送数据的类型支持?ArrayBuffer?,再加上?Frontier?对?Protobuf?支持得比较好,因此和服务端商定采用?Protobuf?作为整个长连接的数据通信协议 。
想要在小程序中使用?Protobuf?,首先将.proto文件转换成js能解析的json,这样也比直接使用.proto文件更轻量,可以使用pbjs工具进行解析:
  1. 安装pbjs工具
  • 基于node.js,首先安装protobufjs
$ npm install -g protobufjs
  • 安装 pbjs需要的库 命令行执行下“pbjs”就ok
$ pbjs
  1. 使用pbjs转换.proto文件
  • 和服务端约定好的.proto文件
// awesome.protopackage wenlipackage;syntax = "proto2";message Header {required string key = 1;required string value = https://www.isolves.com/it/cxkf/ydd/xcx/2020-12-17/2;}message Frame {required uint64 SeqID = 1;required uint64 LogID = 2; required int32 service = 3;required int32 method = 4;repeated Header headers = 5;optional string payload_encoding = 6;optional string payload_type = 7;optional bytes payload = 8;}
  • 转换awesome.proto文件
$ pbjs -t json awesome.proto > awesome.json生成如下的awesom.json文件:
{"nested": {"wenlipackage": {"nested": {"Header": {"fields": {            ...          }        },"Frame": {"fields": {            ...          }        }      }    }  }}