简单二进制编码 (SBE) 常见问题
本文档的目标是解释下列疑问:
- 如何在现货交易API中启用
SBE
响应。 - 如何对
SBE
的响应进行解码。
SBE 是一种用于实现低延迟的序列化格式。
本实现是基于 FIX SBE
规范。
如何获取 SBE 响应
REST API
Accept
报文头必须包含application/sbe
。- 在
X-MBX-SBE
报文头中以<ID>:<VERSION>
的形式提供schema ID
和version
。
样本请求(REST):
curl -sX GET -H "Accept: application/sbe" -H "X-MBX-SBE: 1:0" 'https://api.binance.com/api/v3/exchangeInfo?symbol=BTCUSDT'
注意:
- 如果你只在
Accept
报文头中提供了application/sbe
- 如果交易所不支持
SBE
,你将收到一个406 不可接受的响应。 - 如果在
X-MBX-SBE
报文头中提供的 XML 模式是属于格式错误或不正确的情况,那你得到的响应将会是一个SBE
解码错误。 - 如果
X-MBX-SBE
报文头缺失,那你得到的响应将会是一个SBE
解码错误。
- 如果交易所不支持
- 如果你在
Accept
报文头中同时提供了application/sbe
和application/json
:- 如果交易所不支持
SBE
,那么响应将会被回退到JSON
。 - 如果在
X-MBX-SBE
报文头中提供的 XML 模式是属于格式错误或不正确的情况,那么响应将会被回退到JSON
。 - 如果
X-MBX-SBE
报文头缺失,那么响应将会被回退到JSON
。
- 如果交易所不支持
WebSocket API
- 在请求的URL中添加
responseFormat=sbe
。 - 添加schema ID 和 version 到参数
sbeSchemaId=<SCHEMA_ID>
和sbeSchemaVersion=<SCHEMA_VERSION>
。
样本请求 (WebSocket):
id=$(date +%s%3N)
method="exchangeInfo"
params='{"symbol":"BTCUSDT"}'
request=$( jq -n \
--arg id "$id" \
--arg method "$method" \
--argjson params "$params" \
'{id: $id, method: $method, params: $params}' )
response=$(echo $request | websocat -n1 'wss://ws-api.binance.com:443/ws-api/v3?responseFormat=sbe&sbeSchemaId=1&sbeSchemaVersion=0')
注意:
- 如果你只在连接URL中添加
responseFormat=sbe
:- 如果交易所没有开启 SBE,请求返回 HTTP 400.
- 如果
sbeSchemaId=<SCHEMA_ID>
或者sbeSchemaVersion=<SCHEMA_VERSION>
格式不正确或者无效,请求返回 HTTP 400.
- 如果你同时提供
responseFormat=sbe
和responseFormat=json
, 请求返回 HTTP 400. - 在HTTP握手期间的所有错误响应都编码为JSON,
Content-Type
头设置为application/json;charset=UTF-8
. - 一旦成功建立了启用了SBE的WebSocket会话,在该会话中的所有方法响应都编码为SBE,即使在SBE被禁用的情况下也是如此。
- 这意味着,如果在您的WebSocket连接处于活动状态时禁用了SBE,那么在对您的后续请求做出响应时,您将会收到一个被SBE编码了的“SBE未启用”错误。
- 就目前而言,我们不建议使用
websocat
发送任何请求,因为我们观察到了它解码二进制帧的问题。上面的样本仅用作参考,显示获取SBE响应的URL。
支持的 APIs
目前现货交易的 REST API 和 WebSocket API 支持 SBE
。
SBE 模式
关于对旧版本的支持:
- SBE 模式通过两个 XML 属性进行版本控制,
id
和version
。- 当引入破坏性更改时,
id
会增加。当这种情况发生时,version
会被重置为0。 - 当引入非破坏性更改时,
version
会增加。当这种情况发生时,id
不会被修改。
- 当引入破坏性更改时,
- 当新模式发布时,旧模式会被废止。 即便新模式只引入非破坏性更改,这种情况也会导致废止。
- 已废止的模式将在被废止后依然得到至少6个月的支持。
用以下这个假设的时间线为例:- 3024年1月:发布模式 id 1 version 0。这是第一版,一旦交易所启用
SBE
,用户就立刻可以开始使用该模式。 - 3024年3月:发布模式 id 1 version 1。这个模式引入了一个非破坏性的变化。
- 模式 id 1 version 0 此时已被废止,但还可以至少再被使用6个月。
- 3024年8月:发布模式 id 2 version 0。这个模式引入了一个破坏性的变化。
- 模式 id 1 version 0 已被废止,但还可以再被使用至少1个月。
- 模式 id 1 version 1 此时已被废止,但还可以再被使用至少6个月。
- 3024年9月:自模式 id 1 version 1 发布以来已经过去6个月。
- 模式 id 1 version 0 已被停用。
- 3025年2月:发布模式id 2 版本 1。这个模式引入了一个非破坏性的变化。
- 模式 id 1 version 1 已被停用。
- 模式 id 2 version 0 此时已被废止,但还可以再被使用至少另外6个月。
- 3024年1月:发布模式 id 1 version 0。这是第一版,一旦交易所启用
- HTTP将在针对
X-MBX-SBE header
中已被废止的SBE
模式版本请求的响应中包含一个X-MBX-SBE-DEPRECATED
报文头 。 - 对于WebSocket响应,如果在其连接URL中指定了已弃用的
sbeSchemaId
和sbeSchemaVersion
,sbeSchemaIdVersionDeprecated
字段将被设置为true
。 - 指定已废止的
<ID>:<VERSION>
(REST API)或sbeSchemaId
和sbeSchemaVersion
(WebSocket API)的请求将会返回HTTP 400错误。 - 关于模式生命周期的
JSON
文件将被保存在此仓库中,请看这里。这个文件包含了关于实时交易所和现货测试网的最新、被废止和被停用模式的具体发生日期。
以下是一个基于上述假设时间线的JSON
示例:
{
"environment": "PROD",
"latestSchema": {
"id": 2,
"version": 1,
"releaseDate": "3025-02-01"
},
"deprecatedSchemas": [
{
"id": 2,
"version": 0,
"releaseDate": "3024-08-01",
"deprecatedDate": "3025-02-01"
}
],
"retiredSchemas": [
{
"id": 1,
"version": 1,
"releaseDate": "3024-03-01",
"deprecatedDate": "3024-08-01",
"retiredDate": "3025-02-01",
},
{
"id": 1,
"version": 0,
"releaseDate": "3024-01-01",
"deprecatedDate": "3024-03-01",
"retiredDate": "3024-09-01",
}
]
}
生成解码器:
- 下载模式:
spot_prod_latest.xml
适用于实时交易所。spot_testnet_latest.xml
适用于 现货测试网。
- 克隆并构建
simple-binary-encoding
:
$ git clone https://github.com/real-logic/simple-binary-encoding.git
$ cd simple-binary-encoding
$ ./gradlew
十进制字段编码
不同于 FIX SBE
的规范,十进制字段的尾数和指数字段被单独编码为原始字段,以便使负载量和消息内编码字段的数量达到最小化。
时间戳字段编码
SBE响应中的时间戳(Timestamps)是以微秒为单位。这与包含毫秒时间戳的JSON响应不同。
模式文件中的自定义字段属性
在模式文件中添加了一些以 mbx:
为前缀的字段属性,供文档使用:
mbx:exponent
:指向对应于尾数字段的指数域mbx:jsonPath
:包含了JSON
响应中相应字段的名称mbx:jsonValue
: 包含了JSON
响应中等价ENUM
值的名称