如何使用bit位更高效的声明协议状态

前言
众所周知一个byte由8位bit组成,当我们表示一个状态时没有必要使用整个字节而是转为使用一个字节的一位或连续几位,这样做可以有效的减少协议头长度,提高传输效率。而如何灵活的使用bit表示状态,则需要对位操作比较熟悉。下面通过go语言rpcx协议的设计为示例进行介绍。rpcx使用的字节序是大端序(也是几乎所有网络协议的选择),如果对字节序不够了解的读者可以参考我的这篇博客


rpcx协议
rpcx 的 请求(request)和响应(response)使用相同的数据结构。

一个消息由下面的项组成:

大小
Header 4 字节
Message ID 8 字节
total size 4 字节, 不包含header和它本身, uint32类型
servicePath值的长度 4 字节, uint32类型
servicePath的值 UTF-8 字符串
serviceMethod值的长度 4 字节, uint32类型
serviceMethod的值 UTF-8 字符串
metadata的大小 4 字节, uint32类型
metadata: 格式 size key1 string size value1 string, 可以包含多个
playload的大小 4 字节, uint32类型
playload的值 slice of byte

#4 + #6 + #8 + #10 + (4 + 4 + 4 + 4) 的字节数加起来等于 #3的值。

servicePath、serviceMethod、和meta中的key 、 value 都是UTF-8 字符串。

rpcx 使用 size of an element + element 的格式定义可变长的元素, 就像 TLV, 但是 rpcx 不需要 Type字段, 这是因为 元素的Type 要么是 UTF-8 字符串,要么就是明确的slice。

*对整数使用大端 BigEndian 编码 (integer type, int64, uint32 等等)

我们主要看Header部分的设计
在这里插入图片描述
Header在整个协议中一共占了四个字节,但是却表示了以下大量信息

  • 1、T第一个字节是 0x08, 它是一个魔数 (magic number)
  • 2、第二个字节是 version. 当前的版本是 0.
  • 3、MessageType 可以是:
    0: Request
    1: Response
  • 4、Heartbeat: bool. 指示这个消息是否是heartbeat消息
  • 5、Oneway: bool. true的话意味着服务不需要返回response
  • 6、CompressType: 压缩类型
    0: don’t compress
    1: Gzip
  • 7、MessageStatusType: 指示 response 是一个错误还是正常的返回值
    0: Normal
    1: Error
  • 8、SerializeType: 编解码格式
    0: 使用原始的byte slice
    1: JSON
    2: Protobuf
    3: MessagePack

就是因为协议设计者对字节进行了拆分,使用自己的不同位数表示不同的信息,下面我们直接通过阅读源码的形式进行学习


rpcx header中的位操作

获取和设置指定位bit
先看Message的声明

type Message struct {
   
	*Header
	ServicePath   string
	ServiceMethod string
	Metadata      map[string]string
	Payload       []byte
	data          []byte
}

我们关注的重点就是这个Header,现在来看Header的声明

type Header [12]byte

可以看到Header就是一个字节数组,至于数组长度为什么不是4而是12应该是作者为了协议的扩展性考虑而进行的预留,实际代码中只使用到了前四个字节。

header中前两个信息项都是直接使用了一个字节,我们从第三项开始看起。

MessageType

// MessageType returns the message type.
func (h Header) MessageType() MessageType {
   
	return MessageType(h[2]&0x80) >> 7
}<
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值