GeeRPC第一天 服务端与消息编码(1)-通信过程

时间:2024-11-19 07:01:57

客户端与服务端的通信需要协商一些内容,例如 HTTP 报文,分为 header 和 body 两部分,body 的格式和长度通过 header 中的 Content-TypeContent-Length 指定,服务端通过解析 header 就能够知道如何从 body 中读取需要的信息。对于 RPC 协议来说,这部分协商是需要自主设计的。为了提升性能,一般在报文的最开始会规划固定的字节,来协商相关的信息。比如第 1 个字节用来表示序列化方式,第 2 个字节表示压缩方式,第 3-6 字节表示 header 的长度,7-10 字节表示 body 的长度。

对于 GeeRPC 来说,目前需要协商的唯一一项内容是消息的编解码方式。我们将这部分信息放到结构体 Option 中承载。目前,已经进入到服务端的实现阶段了。

const MagicNumber = 0x3bef5c

type Option struct {
    MagicNumber int
    CodecType   codec.Type
}

var DefaultOption = &Option{
    MagicNumber: MagicNumber,
    CodecType:   codec.GobType,
}

一般来说,涉及协议协商的这部分信息,需要设计固定的字节来传输的。但是为了实现上更简单,GeeRPC 客户端固定采用 JSON 编码 Option,后续的 header 和 body 的编码方式由 Option 中的 CodecType 指定,服务端首先使用 JSON 解码 Option,然后通过 OptionCodecType 解码剩余的内容。即报文将以这样的形式发送:

1
2
| Option{MagicNumber: xxx, CodecType: xxx} | Header{ServiceMethod …} | Body interface{} |
| <------ 固定 JSON 编码 ------> | <------- 编码方式由 CodecType 决定 ------>||
在一次连接中,Option 固定在报文的最开始,HeaderBody 可以有多个,即报文可能是这样的。
1 | Option | Header1 | Body1 | Header2 | Body2 | …