概述

BMTP 是轻量级的二进制传输协议。

该协议的设计目标如下:

  • 减少对处理器以及内存资源的占用
  • 适应于低速率、不稳定的网络环境
  • 基于 TCP/IP 的可靠全双工实时消息传输
  • 基于 发布/订阅 模式的多对多消息传输

控制报文格式

控制报文是 BMTP 进行数据传输的最小单位。客户端和服务端在任何时候都必须连续、完整地发送一个控制报文。

多个控制报文应当按照它们产生的顺序依次发送。

在目前的版本中,控制报文长度最短为 1 字节,最长为 64K 字节。

控制报文由报文头部和有效载荷所组成。

报文头部由嵌套的键值对所组成。最外层的 Key 称作 指令,内部的 Key 则称作 参数。

只有 PUB 指令拥有有效载荷,有效载荷长度由紧跟在报文头部之后的 varint 格式数值所指定。

指令

+---------+-----------------------------------------------+
|   Bit   |  7  |  6  |  5  |  4  |  3  |  2  |  1  |  0  |
+---------+-----------------------------------------------+
|  Byte1  |        Operation Code       | RSV |   Type    |
+---------+-----------------------------------------------+

Operation Code 使用 varint 格式。

Type 列表:

Type 含义 对应 Value 长度
0 bool(1) 0
1 varint 1-10
2 64-bit 8
3 string 1 - 2^64

特殊参数

CONN 指令存在一个特殊参数,长度为 4 字节,值为 ‘BMTP’ 所对应的 ASCII 码。

参数

参数是由一系列的键值对(Key-Value)所组成的。

+---------+-----------------------------------------------+
|   Bit   |  7  |  6  |  5  |  4  |  3  |  2  |  1  |  0  |
+---------+-----------------------------------------------+
|  Byte1  |             Key             | RSV |   Type    |
+---------+-----------------------------------------------+

Key 使用 varint 格式。

控制报文(Packets)

CONN

CONNACK

PUB

PUBACK

SUB

SUBACK

PING

PINGACK

DISCONN

客户端或服务端发送 DISCONN 后必须关闭连接,另一方在接收到 BMTP_DISCONN 后应当关闭连接

建立连接

连接总是由客户端主动发起。连接建立后,如果空闲时间过长,服务端应当关闭连接。

CONN 必须是客户端在连接建立后发送的第一条指令。如果服务端在接收到 CONN 之前收到任何其他指令,服务端应当关闭连接。如果服务端重复收到 CONN 指令,服务端应当关闭连接。

客户端发送 CONN 之后,即可使用 PUB 向服务端推送消息。

客户端发送 SUB 之后,服务端方可向客户端推送消息。

消息传输

BMTP 服务端和客户端在处理消息时,应当将消息保存到队列中,并在发送窗口可用时根据接收消息的顺序依次推送。

服务端和客户端必须为 PUB 的每一条消息分配一个互不重复的流标识符。如果没有可用的流标识符,则必须暂停消息推送。

当接收到 PUBACK 时,必须将该消息所指定的流标识符释放。如果未收到 PUBACK,则该流标识符将在该连接的生命周期中被永久占用。

未收到 PUBACK 的消息应当在连接断开时重新写回到队列中,以允许该消息被重新处理。

数据流

为了实现全双工实时消息传输,BMTP 数据包传输建立在虚拟的数据流上。

数据包都会指定一个或者默认拥有一个数据流。在同一个数据流内部,BMTP 使用请求/响应模型。不同的数据流之间互不影响。

在目前的版本中,客户端和服务端各自可以建立最多 256 个数据流。

离线消息与消息堆积

BMTP 服务端应当支持离线消息和消息堆积。

如果服务端未能支持离线消息,则应当在没有任何订阅者在线时返回 PUBACK 响应并将状态码设置为 0x02。

如果服务端未能支持消息堆积,则应当在没有任何空闲的订阅者在线时返回 PUBACK 响应并将状态码设置为 0x03。

关闭连接

当服务端主动关闭连接时,可以不发送 DISCONN 而直接关闭连接。

当客户端主动关闭连接时,应当先发送 DISCONN 再关闭连接。

数据安全

BMTP 不包含数据加密与安全校验机制。如果需要保证数据安全,应当先建立 TLS 连接,再建立 BMTP 连接。

异常