简单二进制编码 (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。
FIX API
详情请参见 FIX API 的 SBE 部分
支持的 APIs
REST API、WebSocket API 和 FIX API 对现货(SPOT)支持 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。这是第一版,一旦交易所启用
- 当 REST API 请求中在
X-MBX-SBE头部里指定了已废止的<ID>:<VERSION>时:- HTTP 响应将包含
X-MBX-SBE-DEPRECATED头部 - SBE 响应将使用可兼容的最高版本模式进行编码
- 例如,从2025-08-27 开始,针对
X-MBX-SBE: 3:0的请求将收到以模式3:1进行编码的响应。根据 FIX SBE 规范,模式3:0的 SBE 解码器应该能够顺利地对模式3:1进行解码。
- 例如,从2025-08-27 开始,针对
- HTTP 响应将包含
- 当 WebSocket API 连接 URL 中指定了已废止的
sbeSchemaId和sbeSchemaVersion时:- 所有
WebSocketResponseSBE 消息中的字段sbeSchemaIdVersionDeprecated将被设置为true - 所有 SBE 响应将使用可兼容的最高版本模式进行编码
- 例如,从2025-08-27 开始,针对
sbeSchemaId=3&sbeSchemaVersion=0的请求将收到以模式3:1进行编码的响应。根据 FIX SBE 规范,模式3:0的 SBE 解码器应该能够顺利地对模式3:1进行解码。
- 例如,从2025-08-27 开始,针对
- 所有
- 对于 FIX API,当 SBE 请求消息头指定了已弃用的
schemaId和version时:- 在
LogonAck消息中,字段sbeSchemaIdVersionDeprecated将被设置为true - 所有 SBE 响应消息将使用所提供
schemaId的最高模式版本进行编码
- 在
- 指定已废弃的 schemaId/version 的请求将失败,返回 HTTP 400(REST 和 WebSocket)或拒绝消息(FIX API)。
- 在 SBE 模式 3:0 中,为每个
enum添加了名为NonRepresentable的validValue。接收到该值表示使用最新模式时有额外数据可用。 - 在 SBE 模式 3:1 中,添加了名为
NonRepresentableMessage的消息。接收到该消息表示使用最新模式时有额外数据可用。该消息可能作为顶层消息接收,或当data字段的type为messageData、messageData8、messageData16、optionalMessageData或optionalMessageData16时嵌入在data字段中。 - 关于模式生命周期的
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",
}
]
}
生成解码器:
- 下载模式:
- REST/WebSocket API:
spot_prod_latest.xml用于实时交易所。spot_testnet_latest.xml用于现货测试网。
- FIX API:
spot_fix_prod_latest.xml用于实时交易所。spot_fix_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值的名称