香蕉协议规范

简介

香蕉是一种高效且可扩展的协议,用于发送和接收 s-表达式。在此上下文中,s-表达式是指由字节、整数、大整数、浮点数和/或 s-表达式组成的列表。不支持 Unicode(但可以在进入和离开香蕉的途中编码为字节并解码为字节)。不支持的类型必须在使用香蕉发送之前转换为支持的类型。

香蕉编码

香蕉协议是由元素组成的字节流。每个元素都具有以下通用结构 - 首先,以 128 为基数编码的元素长度,最低有效位在前。例如,长度 4674 将发送为 0x42 0x24 。对于某些元素类型,长度将被省略(例如浮点数)或具有不同的含义(它是整数元素的实际值)。

在长度之后是一个分隔符字节,它告诉我们这是哪种元素。根据元素类型,接下来将跟随长度中指定的字节数。字节的高位始终被设置,因此我们可以将其与长度区分开来(因为长度字节使用 128 为基数,它们的高位永远不会被设置)。

元素类型

给定一系列为我们提供长度 N 的字节,这些是不同的分隔符字节

列表 – 0x80

以下字节是 N 个元素的列表。列表可以嵌套,子列表对父列表只算作一个元素(无论子列表包含多少个元素)。

整数 – 0x81

此元素的值是正整数 N。后面的字节不属于此元素。整数的值可以为 0 <= N <= 2147483647。

字符串 – 0x82

以下 N 个字节是一个字符串元素。

负整数 – 0x83

此元素的值是整数 N * -1,即 -N。后面的字节不属于此元素。负整数的值可以为 0 >= -N >= -2147483648。

浮点数 - 0x84

接下来的 8 个字节是以 IEEE 754 浮点数“双精度格式”位布局编码的浮点数。不应定义任何长度字节。

大整数 – 0x85

此元素的值是正大整数 N。后面的字节不属于此元素。大整数没有大小限制。

大负整数 – 0x86

此元素的值是负大整数 -N。后面的字节不属于此元素。大整数没有大小限制。

大整数用于任意长度的整数。常规整数类型(正数和负数)限制为 32 位值。

示例

以下是一些元素及其编码的示例 - 类型字节以粗体标记

1

0x01 **0x81**

-1

0x01 **0x83**

1.5

**0x84**  0x3f 0xf8 0x00 0x00 0x00 0x00 0x00 0x00

"hello"

0x05 **0x82**  0x68 0x65 0x6c 0x6c 0x6f

[]

0x00 **0x80**

[1, 23]

0x02 **0x80**  0x01 **0x81**  0x17 **0x81**

123456789123456789

0x15 0x3e 0x41 0x66 0x3a 0x69 0x26 0x5b 0x01 **0x85**

[1, ["hello"]]

0x02 **0x80**  0x01 **0x81**  0x01 **0x80**  0x05 **0x82**  0x68 0x65 0x6c 0x6c 0x6f

配置文件

香蕉协议是可扩展的。因此,它支持配置文件的概念。配置文件允许开发者扩展香蕉协议,添加新的元素类型,同时仍然保持与不支持扩展的实现的向后兼容性。每个会话中使用的配置文件在握手阶段确定(见下文)。

配置文件由唯一的字符串指定。本规范定义了两个配置文件 - "none""pb""none" 配置文件是所有香蕉实现都应支持的标准配置文件。将来可能会添加其他配置文件。

配置文件定义的扩展只有在客户端和服务器选择该配置文件时才能使用。

“none” 配置文件

“none” 配置文件与上面列出的分隔符类型相同。强烈建议所有香蕉客户端和服务器都支持“none” 配置文件。

“pb” 配置文件

“pb” 配置文件旨在与运行在香蕉之上的 Perspective Broker 协议一起使用。基本上,它将常用的 PB 字符串转换为更短的版本,从而最大限度地减少带宽使用。它以一个字节开头,告诉我们将其转换为哪个字符串元素,并以分隔符字节 0x87 结尾,该字节不应以长度为前缀。

0x01

‘None’

0x02

‘class’

0x03

‘dereference’

0x04

‘reference’

0x05

‘dictionary’

0x06

‘function’

0x07

‘instance’

0x08

‘list’

0x09

‘module’

0x0a

‘persistent’

0x0b

‘tuple’

0x0c

‘unpersistable’

0x0d

‘copy’

0x0e

‘cache’

0x0f

‘cached’

0x10

‘remote’

0x11

‘local’

0x12

‘lcache’

0x13

‘version’

0x14

‘login’

0x15

‘password’

0x16

‘challenge’

0x17

‘logged_in’

0x18

‘not_logged_in’

0x19

‘cachemessage’

0x1a

‘message’

0x1b

‘answer’

0x1c

‘error’

0x1d

‘decref’

0x1e

‘decache’

0x1f

‘uncache’

协议握手和行为

连接的起始方将被称为“客户端”,另一方将被称为“服务器”。

连接后,服务器将向客户端发送一个字符串元素列表,表示它支持的配置文件。建议将 "none" 包含在此列表中。然后,客户端从该列表中向服务器发送一个字符串,告诉服务器它要使用哪个配置文件。此时,整个会话将使用此配置文件。

建立配置文件后,双方就可以开始交换元素。消息的顺序或依赖关系没有限制。任何此类限制(例如,“服务器只能在响应客户端的请求时向客户端发送元素”)都是特定于应用程序的。

在收到非法消息、握手失败等情况下,香蕉客户端或服务器应关闭其连接。