《Netty权威指南》笔记——Netty多协议开发和应用
第12章 私有协议栈开发
私有协议介绍
私有协议具有封闭性, 垄断性,排他性的特点. Netty提供的异步TCP协议栈开发一个私有协议栈, 该协议栈被命名为Netty协议栈.
Netty协议栈功能设计
Netty协议栈用于内部各模块之间的通信, 基于TCP/IP协议栈, 一个类HTTP协议的应用层协议栈, 相比于传统的标准协议栈, 它更加轻巧,灵活和实用
网络拓扑图
Netty节点没有服务端和客户端的区分, 谁首先发起连接, 就作为客户端, 另一方自然成为服务端. 一个Netty节点既可以作为客户端连接另外的Netty节点, 也可以作为Netty服务端被其他Netty节点连接.
协议栈功能描述
- 基于Netty的NIo通信框架, 提供高性能的异步通信能力
- 提供消息的编解码框架, 可以实现POJO的序列化和反序列化
- 提供基于IP地址的白敏弹接入认证机制
- 链路的有效性校验机制
- 链路的断连重连机制
通信模型
消息定义
由两个部分组成:
消息头
消息体
Netty协议的编解码规范
1. Netty协议编码
ercCode,length,sessionID, type, Priority:
put()默认byte输入, 其他类型用特定put, e.g. putInt() , putLong()
attachment:
- 首先对附件个数进行编码
- 然后对Key进行编码
- 长度
- 再转换成byte数组之后编码的内容
body:
通过JBoss Marshalling 序列化为Byte数组, 然后调用java.nio.ByteBuffer.put(byte [] src)
将其写入ByteBuffer缓冲区中.
2. Netty协议的解码
ercCode,length,sessionID, type, Priority:
get()默认byte输入, 其他类型用特定get, e.g. getInt() , getLong()
attachment:
创建一个新的attachment对象, 调用java.nio.ByteBuffer.getInt()
获取附件的长度
- 如果长度0, 结束解码
- 如果长度不为0, 解码消息体, 如果非空, 根据擦和高难度通过for循环进行解码
body:
通过JBoss marshaller解码
链路的建立
链路建立需要通过基于IP地址或者号段的黑白名单安全认证机制.
作为样例, 本协议使用基于IP地址的安全认证, 如果有多个IP, 通过逗号进行分割. 在实际商用项目中, 安全认证机制会更加严格, 例如通过密钥对用户名和密码进行安全认证
-
客户端与服务器链路建立成功之后, 由客户端发送握手请求消息, 握手请求消息的定义如下
- 消息头的type字段值为3
- 可选附件个数为0
- 消息体为空
- 握手消息长度为22个字节
-
服务端接收到客户端的握手请求消息之后, 如果IP校验通过, 返回成功应答消息给客户端, 应用链路建立成功. 握手应答消息定义:
- 消息头的type字段值为4
- 可选附件个数为0
- 消息体为byte类型的结果
- “0” 表示认证成功
- “-1” 表示认证失败
链路的关闭
由于采用长连接通信, 在正常的业务运行期间, 双方通过心跳和业务消息维持链路, 任何一方都不需要主动关闭连接
除非出现以下情况
- 当对方宕机或者重启, 会主动关闭链路, 另一方读取