This repository was archived by the owner on Sep 25, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Pomelo 协议
HellGame edited this page Jun 4, 2015
·
16 revisions
-###背景 -0.3版本之前的Pomelo采用json格式的文本作为客户端和服务器的通讯协议,方便协议定制和修改,但同时也带来了较多的通讯冗余数据。Pomelo在0.3版本,底层通讯提供了二进制版本通讯协议的支持,同时提供了route字典压缩和protobuf压缩,提高带宽利用率,以满足诸如移动环境的需求。同时上层接口仍保持json格式的接口,对0.3版本之前的代码不产生任何影响,也保留了开发的便利。
-Pomelo的二进制协议包含两层编码:package和message。Message层主要实现route压缩和protobuf压缩,message层的编码结果将传递给package层。Package层主要实现Pomelo应用基于二进制协议的握手过程,心跳和数据传输编码,package层的编码结果可以通过tcp,websocket等协议以二进制数据的形式进行传输。Message层编码可选,也替换成其他二进制编码格式,都不影响package层编码和发送。
- - -
-Package协议主要用来封装在面向连接的二进制流的通讯协议(如:tcp)上的Pomelo数据包。Package分为控制包和数据包两种类型。前者用来实现Pomelo应用层面的控制流程,包括客户端和服务器的握手,心跳和服务器主动断开连接的通知等控制信息。后者则是用来在客户端和服务器之间传输应用数据。
-+ type - package类型,1个byte,取值如下。
-
- 0x01: 客户端到服务器的握手请求以及服务器到客户端的握手响应
-
- 0x02: 客户端到服务器的握手ack
-
- 0x03: 心跳包
-
- 0x04: 数据包
-
- 0x05: 服务器主动断开连接通知 -+ length - body内容长度,3个byte的大端整数。 -+ body - 二进制的传输内容。
-``` -{
- 'sys': {
- 'version': '1.1.1',
- 'type': 'js-websocket'
- },
- 'user': {
- // any customized request data
- } -} -```
-+ sys.version - 客户端的版本号。每个客户端SDK的每一个版本都有一个固定的版本号。在握手阶段客户端将该版本号上传给服务器,服务器可以由此来判断当前客户端是否合适与服务器通讯。 -+ sys.type - 客户端的类型。可以通过客户端类型和版本号一起来确定客户端是否合适。
-``` -{
- 'code': 200, // result code
- 'sys': {
- 'heartbeat': 3, // heartbeat interval in second
- 'dict': {}, // route dictionary
- 'protos': {} // protobuf definition data
- },
- 'user': {
- // any customized response data
- } -} -```
-+ code - 握手响应的状态码。目前的取值:200代表成功,500为处理用户自定义握手流程时失败,501为客户端版本号不符合要求。 -+ sys.heartbeat - 心跳时间间隔,单位为秒。 -+ dict - route字段压缩的映射表 -+ protos - protobuf压缩的数据定义
-从上图可以看出,Pomelo消息头是可变的,会根据具体的消息类型和内容而改变。其中,flag位是必须的,占用一个byte,它决定了后面的消息类型和内容的格式。message id和route则是可选的,具体的长度要根据实际内容和flag来决定。 -##### 标志位Flag -Flag占用Message头的第一个byte,其内容如下
-现在只用到了其中的4个bit,这四个bit包括两部分,占用4个字节的message type字段和占用1个字节的route标识,其中: -* message type用来标识消息类型,范围为0~7,现在消息共有四类,request,notify,response,push,值的范围是0~3。不同的消息类型有着不同的消息内容,下面会有详细分析。 -* 最后一位的route表示route是否压缩,影响route字段的长度。 -这两部分之间相互独立,互不影响。
-#####Route标志位 -route主要分为压缩和未压缩两种,由flag的最后一位(route位)指定,当flag中的route标志为0时,表示未压缩的route,为1则表示是压缩route。route通过系统生成和用户自定义的字典进行压缩,具体内容见(pomelo压缩协议-字典压缩)。
-上图是不同的flag标志对应的route字段的内容: -* flag的最后一位为1时,后面跟的是一个uInt16表示的route字典编号,需要通过查询字典来获取route。 -* flag最后一位为0是,后面第一位unt8的byte,用来表示route的字节长度。之后是通过utf8编码后的route,其长度就是前面一位byte的uInt8的值。
-
-
-
-
-
-
-
-