Protocol buffers是google提供的一种将结构化数据进行序列化和反序列化的方法,其优点是语言中立,平台中立,可扩展性好,目前在google内部大量用于数据存储,通讯协议等方面。PB在功能上类似XML,但是序列化后的数据更小,解析更快,使用上更简单。用户只要按照proto语法在.proto文件中定义好数据的结构,就可以使用PB提供的工具(protoc)自动生成处理数据的代码,使用这些代码就能在程序中方便的通过各种数据流读写数据。PB目前支持Java, C++和Python3种语言。另外,PB还提供了很好的向后兼容,即旧版本的程序可以正常处理新版本的数据,新版本的程序也能正常处理旧版本的数据。我们主要研究PB在C++语言的使用,PB的编译安装比较简单,C++的库使用make完成,java使用maven完成,python直接使用setup命令完成。

Protocol Buffers要如何用在socket通信的通信协议中?可以大概地说一下:你需要根据你的协议编写一个.proto文件,此文件的格式是按Protocol Buffers的要求书写的。然后用Protocol Buffers编译器生成这个文件对应的类文件(包括一个.h文件和一个.cc文件),然后在你的程序中include生成的头文件,当需要发送socket消息的时候,先用这个类的对象的SerializeToString()方法,生成一个字符串,这个字符串也就相当于我们传统意义上的编码过的消息,然后在socket消息的接收方,使用ParseFromString()方法,就可以将消息中包含的数据解析到生成的类的成员变量中,就可以直接取出来用了。整个过程不需要你去考虑编码、解码,就算更改了协议,修改工作也非常方便。

零、为什么要研究ProtoBuff

需求是最大的驱动,加入百度Hi团队一个多月了,这一个多月的时间里做了许多以前没有做过的事。针对Hi用户的反馈,移动端Hi对流量的消耗太大。Hi消息传输的格式目前主要有2种,一种是公司定义的一种nshead+mcbody的形式,这种方式类似于我们今天所要讲解的ProtoBuff,统一使用这种方式也能够减小传输流量,而且数据安全性也更高;另一中方式就是比较古老的文本协议格式了。公司决定对现有的文本协议进行优化。怎么优化呢?Hi目前使用文本协议在客户端和服务端进行信息等传输,这里所说的消息包括CS之间Request包、ACK包,或者服务端的Notify包等等,这些包里面的包括的内容不仅仅是聊天信息,也包括联系人状态变更等各种通知信息。

总得来说,Hi消息传输的报文格式可以概括为:header + body,header主要由一些键值对构成,而body则更多的是使用xml的格式。最终决定使用高大上的ProtoBuff对当前的文本协议进行改进,在这里先列出具体的实现思路:

  1. 现有的消息包括header和body两个部分,我们需要一个转换工具,分析现有报文的定义要求,生成一个消息格式xml文件:即包括了header和body的一个xml文件;
  2. 根据该xml格式生成proto的描述文件,然后通过Proto编译生成对应的.h和.cc文件;
  3. 最后就是要考虑和现有协议的转换了,庞大的系统兼容性是不可忽略的,即服务端添加一个专门协议转换的模块,分别针对上行和下行进行原有报文到pb报文的相互转换。

一、ProtoBuff开发三部曲

所谓开发三部曲,即:

  1. 定义描述文件,即.proto文件;
  2. 使用proto编译器生成该描述文件对应的定义文件,C++包括.h和.cc;
  3. 使用定义文件中提供的ProtoBuff的API读写消息。

举个简单的实例,百度Hi在拉取群列表时的协议定义为group:get_list,我们在描述文件中定义如下:

我们如何去按照这个定义要求去封包呢?直接看代码:

上图中88行中的日志就是将我们的PB报文以字符串形式打印出来,便于我们调试,即DebugString方法。在日志中我们可到PB结构如下:

二、序列化与反序列化

继续看代码,我们已经准备好了PB的封包,序列化之后就可以通过连接发出去了

百度Hi-Server在接收到PB包之后通过一系列的处理,会返回一个group:get_list的ACK包回来,我们怎么把回包拿出来并转化成我们现有的文本协议形式呢?继续看代码:

红色框图中的部分就是反序列化的过程,通过反序列化之后,我们就可以调用ProtoBuff定义的API去解析该PB报文了。

三、完成协议的测试

我们的测试目的就是保证PB与原协议的兼容性,换句话说就是转换后的数据一致性,我们在ImpPacket中重载了==运算符,完成比较的过程,即分别对ImpPacket中的header和body做比较,header是由一些map构成的,body则是xml构成的。我们的比较就是分别对header和body中的map和xml进行比较。

xml的比较代码如下(部分):

这就是该博文的所有内容,6个不同的协议,耗时2天时间完成,期间还踩到老代码中的一个坑,gdb调试才定位到,累觉不爱。感谢阅读,Published by Windows LiveWriter.

筒子们,使用Protobuf优化你的协议的更多相关文章

  1. 【MINA】用protobuf做编解码协议

    SOCKET协议 支持java serial 与 AMF3的混合协议,目前没有基于xml 与 json的实现. 协议说明: * 9个字节协议头+协议体. * * 协议头1-4字节表示协议长度 =协议体 ...

  2. SuperSocket与Netty之实现protobuf协议,包括服务端和客户端

    今天准备给大家介绍一个c#服务器框架(SuperSocket)和一个c#客户端框架(SuperSocket.ClientEngine).这两个框架的作者是园区里面的江大渔. 首先感谢他的无私开源贡献. ...

  3. 使用Protobuf定义网络协议

    准备工具: 工具下载地址如下:https://github.com/protocolbuffers/protobuf/releases/tag/v3.6.1,主要使用到的文件有: protoc.exe ...

  4. 自定义兼容多种Protobuf协议的编解码器

    <从零开始搭建游戏服务器>自定义兼容多种Protobuf协议的编解码器 直接在protobuf序列化数据的前面,加上一个自定义的协议头,协议头里包含序列数据的长度和对应的数据类型,在数据解 ...

  5. Quick UDP Internet Connections 让互联网更快的协议,QUIC在腾讯的实践及性能优化

    https://mp.weixin.qq.com/s/44ysXnVBUq_nJByMyX9n5A 让互联网更快:通往QUIC之路 原创: 史天 翻译 云技术实践 8月15日 QUIC(Quick U ...

  6. 全面解密QQ红包技术方案:架构、技术实现、移动端优化、创新玩法等

    本文来自腾讯QQ技术团队工程师许灵锋.周海发的技术分享. 一.引言 自 2015 年春节以来,QQ 春节红包经历了企业红包(2015 年).刷一刷红包(2016 年)和 AR 红包(2017 年)几个 ...

  7. 微服务性能优化之thrift改造

    在我当前所做的web项目中,采用前后端分离模式前端通过Django 提供restful接口,后端采用微服务架构,微服务之间的调用采用jsonrpc,由于微服务之间的调用很频繁,导致前端得到的响应很慢, ...

  8. 转: 基于netty+ protobuf +spring + hibernate + jgroups开发的游戏服务端

    from: http://ybak.iteye.com/blog/1853335 基于netty+ protobuf +spring + hibernate + jgroups开发的游戏服务端 游戏服 ...

  9. NSCache和NSURLCache、网络缓存优化

    本文目录 一种缓存优化方案 响应头'Last-Modified'和请求头'If-Modified-Since' 'Keep-Alive'响应头和不离线的URLSession 'Expires'响应头 ...

随机推荐

  1. MovieReview—Despicable Me 3(神偷奶爸3)

    Minions&Unicorn         The film focuses on the story of Grew and the bastard Bled. A variety of ...

  2. unity热更新方案对比

    Unity应用的iOS热更新 •  什么是热更新 •  为何要热更新 •  怎样在iOS 上对Unity 应用进行热更新 •  支持Unity iOS 热更新的各种Lua 插件的对照 什么是热更新 • ...

  3. jQuery JavaScript Library v3.2.1

    /*! * jQuery JavaScript Library v3.2.1 * https://jquery.com/ * * Includes Sizzle.js * https://sizzle ...

  4. Vmware 安装CentOS7时连不上网问题的解决

    在VmWare 上安装Centos7时,装好vmware后还是连不上网,通过查找资料原来是因为有线网卡没有激活,默认centos和redhat7都是不启用有线网卡的,要么手动开启,要么安装时直接启用! ...

  5. Tomcat:使用startup.bat启动tomcat遇到报错

    问题:使用startup.bat启动tomcat的时候报错,按照网页上的办法都试了一遍,但是没有解决问题.命令窗口启动tomcat会一闪而过,然后退出. 解决:1 检查环境变量配置是否有问题: CAT ...

  6. mysql5.7.24 解压版安装步骤以及遇到的问题

    1.下载 https://dev.mysql.com/downloads/mysql/ 2.解压到固定位置,如D:\MySQL\mysql-5.7.24 3.添加my.ini文件 跟bin同级 [my ...

  7. SpringBoot(一)_Eclipse的安装和使用

    1.Eclipse中安装STS插件: Help -> Eclipse Marketplace… Search或选择“Popular”标签,选择Spring Tool Suite (STS) fo ...

  8. VueX源码分析(1)

    VueX源码分析(1) 文件架构如下 /module /plugins helpers.js index.esm.js index.js store.js util.js util.js 先从最简单的 ...

  9. tmp_获取下一个回文数

    直接拿之前一次竞赛中写的code,稍微完善了点,后面有机会在优化 uint64_t GetNextPalindrome(uint64_t data) { //100以内的数字已经特殊考虑过,不存在差值 ...

  10. python入门学习笔记1:Python与C的简单区别

    转载于:https://www.cnblogs.com/mlgjb/p/7892130.html 并做适当修改 一:简单比较   C语言 python 执行速度 快 慢 跨平台 不可以 可以 用途 操 ...