-
Notifications
You must be signed in to change notification settings - Fork 1
Implement_bsoa_protocol
Geng Zhang edited this page Mar 5, 2017
·
1 revision
bsoa 协议是 BSOA 框架自带的基于 TCP 的二进制自定义协议,具有如下特点:
- 魔术位头区分
- 头部可扩展,序列化与body隔离
主要分为三部分:定长 Head、变长 Head、变长 Body 部分。
-------------------------
| Fixed Head(16B) |
------------------------
| Variable Head |
------------------------
| B o d y |
-------------------------
定长头部直接拼装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
变长头部其实就是一个可扩展的 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是对请求参数或者响应参数的序列化后的 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 | 服务端要重启或者关闭前,将向该端口下的全部长连接发送即将关闭命令,客户端可以提前不调这个服务端地址。 |
Copyright www.bsoa.io 2016-2017