Skip to content

Implement_bsoa_protocol

Geng Zhang edited this page Mar 5, 2017 · 1 revision

BSOA协议

bsoa 协议是 BSOA 框架自带的基于 TCP 的二进制自定义协议,具有如下特点:

  1. 魔术位头区分
  2. 头部可扩展,序列化与body隔离

协议数据

主要分为三部分:定长 Head变长 Head变长 Body 部分。

-------------------------
|    Fixed Head(16B)    |
------------------------
|    Variable Head      |
------------------------
|       B o d y         |
-------------------------

定长 Head

定长头部直接拼装byte[]。无需序列化

------0----|-----1----|-----2----|-----3----|-----4----|-----5----|-----6----|-----7-----
|    magic code[0]    |              TotalLength[1]               |    HeadLength[2]    |
------8----|-----9----|----10----|----11----|----12----|----13----|----14----|----15-----
|msgType[3]| protocol |   codec  | compress |              message Id[7]                |
-----------|----------|----------|----------|----------|----------|----------|-----------
[0]魔术位:2 Byte
[1]总长度:4 Byte,数值包括魔术位和自己。
[2]头部长度:1 Byte,包括自己加上后面 Body 前的全部长度
[3]方向+消息类型:1 Byte,方向(2bit)加上消息类型(6bit)
[4]协议类型:1 Byte
[5]序列化类型:1 Byte,指 Body 的序列化
[6]压缩类型:1 Byte
[7]消息Id:4 Byte

变长 Head

变长头部其实就是一个可扩展的 Map<Byte,Object> 。对应的 Key 参见io.bsoa.rpc.message.HeadKey
目前支持类型:void(代表是个映射)/int/String/byte/short/long/boolean
采用的序列化为固定的自定义序列化。和 Body 序列化无关。

先写Map长度:1 Byte

然后循环每个Map.Entry
    type   : 序列化方式                           长度
    void   : 1位key+1位标识(0)+2位ref值<br/>       3
    int    : 1位key+1位标识(1)+4位值<br/>          6
    String : 1位key+1位标识(2)+2位长度+N位值<br/>   4+n
    byte   : 1位key+1位标识(3)+1位值<br/>          3
    short  : 1位key+1位标识(4)+2位值<br/>          4
    long   : 1位key+1位标识(5)+8位值<br/>          10
    boolean: 1位key+1位标识(6)+1位值<br/>          3

变长 Body

变长Body是对请求参数或者响应参数的序列化后的 byte[]。
序列化类型取自定长 Head 里的 codec
注意:如果定长 Head 里的compress不为空,那么代表数据经过了压缩。需要先解压缩在反序列化。

协议常量

###调用方向 参见定长Head里的方向+消息类型字段。
目前有双向和单向两种。

###消息类型 参见定长Head里的方向+消息类型字段。
目前有心跳请求/响应、协商请求/响应、RPC请求/响应。

###变长 HeadKey 对应的 Key 参见 io.bsoa.rpc.message.HeadKey

协商机制

从变成Head里密码可以看到一种void类型的Key,代表这是一个反向映射值。
意思就是对方发来一个 key=2,其实2代表的是一个字符串。
那么这个映射关系是从哪里来的呢,这就用到了bsoa协议的协商机制。

当然,协商机制不是协议必须的,只是个优化选项。 目前与的协商如下:

协商 方向 命令 说明
版本 客户端->服务端 version 客户端发送自己版本给服务端,服务端返回自己版本给客户端。双方都保存对方版本到长连接上下文中
序列化 客户端->服务端 codec 客户端将自己要使用的序列化发送给服务端,服务端判断是否支持,可以返回推荐的序列化给客户端等
应用信息 客户端->服务端 app 客户端将自己的应用信息(包括应用Id,应用名称,应用实例Id等发送给服务端,服务端保存到长连接上下文中
头部缓存 客户端->服务端 headkey 客户端先根据要缓存的头部(例如接口名方法名等常量)生成一个缓存Id,发送给服务端,服务端保存到长连接上下文成功后,返回给客户端ack,客户端页将缓存放入长连接上下文。后续遇到这个Head的值就用一个ref值代替。
服务端忙 服务端->客户端 serverbusy 服务端遇到线程池耗尽时,将向该端口下的全部长连接发送服务端忙命令,客户端可以减少该服务端地址的调用次数,或者不调这个服务端地址。
服务端关闭 服务端->客户端 serverclosing 服务端要重启或者关闭前,将向该端口下的全部长连接发送即将关闭命令,客户端可以提前不调这个服务端地址。

Clone this wiki locally