Skip to content

Latest commit

 

History

History
168 lines (133 loc) · 5.54 KB

File metadata and controls

168 lines (133 loc) · 5.54 KB

协议定义

如无特殊说明:

  • 本协议中所有字符串均采用ASCII编码表示为二进制值, 如"ABC"表示字节序列[65, 66, 67], 而"ABC\0"表示[65, 66, 67, 0]
  • 本协议中所有整数均采用网络字节序的2的补码表示

(I) 握手

1. 请求

客户端向服务器发起TCP连接。在TCP连接建立后,客户端应首先发送消息1

消息1

+--------+------------------+------------------+
| "PSMB" | version (uint32) | options (uint32) |
+--------+------------------+------------------+

载荷说明:

  • "PSMB":协议头
  • version:版本号,服务器据此判断服务器和客户端双方的协议是否兼容
  • options:初始参数。目前,所有位均保留供将来使用,应设置为全零

2. 响应

  1. 服务端读取4个字节,并判断是否为"PSMB"。如果不是,立刻断开连接。
  2. 服务端读出一个4字节无符号数,记为ver,判断ver是否为其兼容的版本号。如果不是,返回消息2,并立刻断开连接。
  3. 服务端读出32位长的比特数组,记为options,判断options的比特是否全部为零。如果不是,立刻断开连接。如果是,返回消息3

消息2

+--------------------------+
| "UNSUPPORTED PROTOCOL\0" |
+--------------------------+

载荷说明:

  • "UNSUPPORTED PROTOCOL\0":表示该协议版本不受服务端支持

消息3

+--------+------------------+
| "OK\0" | options (uint32) |
+--------+------------------+

载荷说明:

  • "OK\0":表示服务端接受了客户端的传入连接,连接成功建立
  • options:服务端向客户端发送的选项。在当前版本,该字段应为全零

3. 客户端处理

  • 客户端读入一个以\0结尾的字符串,如果是"UNSUPPORTED PROTOCOL\0",断开连接; 如果是"OK\0",且继续读取32个比特全为0,则进入状态(II);如果不是,断开连接

(II) 模式选择

1. 模式选择

客户端选择本连接的类型,如果是PUBLISH,则发送消息4;如果是SUBSCRIBE,则发送消息5

消息4

+-------+--------------------------------------+
| "PUB" | topic_id (str, terminated with '\0') |
+-------+--------------------------------------+

载荷说明:

  • "PUB":表示该连接为PUBLISH类型。 客户端发送要发布的消息,服务端接收消息, 并转发给订阅该话题的其他客户端
  • topic_id:该连接发布的消息的话题标识符,是一个字符串

消息5

+-------+------------------+----------------------------------------+-----+
| "SUB" | options (uint32) | id_pattern (str, terminated with '\0') | ... |
+-------+------------------+----------------------------------------+-----+

载荷说明:

  • "SUB":表示该连接为SUBSCRIBE类型。 客户端提供一个匹配模式串,服务端将来自所有标识符匹配该模式串的话题的消息转发给客户端。
  • id_pattern:模式串,一个PCRE正则表达式字符串。
  • ...:可选载荷。按照从最低有效位到最高有效位的顺序遍历options中的每一位,如果该位为1,则读入一个选项。
    • 第0位:ALLOW_HISTORY。如果该为为1,则服务器将向客户端发送它没有接收过的所有消息,即有记忆功能。 选项:
      +------------------------+
      | subscriber_id (uint64) |
      +------------------------+
      

2. 响应

服务端接收客户端的命令后,判断命令是否合法:读取3个字节,如果既不是"PUB"也不是"SUB",返回消息6并断开连接。 否则,如果接受该命令,返回消息7并进入状态(III);如果拒绝该命令,返回消息8并保持在该状态。

消息6

+-----------------+
| "BAD COMMAND\0" |
+-----------------+

消息7

+--------+
| "OK\0" |
+--------+

消息8

+------------+--------------------------------------------------------------------------------------------+
| "FAILED\0" | error_message (str, terminated with '\0', read up to 128 Bytes including terminating '\0') |
+------------+--------------------------------------------------------------------------------------------+

(III) 消息交换

如果是PUBLISH模式,客户端向服务器发送消息,记主动方为客户端;如果是SUBSCRIBE模式,服务器向客户端发送消息,记主动方为服务端。 无论是在哪种模式,主动方发送的消息都应为消息9消息10的一种。

消息9

+-------+-------------------------+----------------------------------+
| "MSG" | message_length (uint64) | message (`message_length` bytes) |
+-------+-------------------------+----------------------------------+

载荷说明:

  • "MSG":表示该消息是一个携带一个上层消息的报文
  • message_length:上层消息长度
  • message:上层消息,长度为message_length字节

消息10

+-------+
| "NOP" |
+-------+

载荷说明:

  • "NOP":表示该消息是一个空指令,什么都不做(当经过NAT设备防火墙时,可定时发送此消息以保持TCP连接)。接收方总是返回一个消息12

消息11

+-------+
| "BYE" |
+-------+

载荷说明:

  • "BYE":表示主动方将要终止连接。接收到此消息后,被动方(主动方的对方)也要终止连接

消息12

+-------+
| "NIL" |
+-------+

载荷说明:

  • `"NIL":表示一个空消息。接收方应总是丢弃该消息