APP下载

基于Google Protocol Buffer的即时通讯系统设计

2017-03-29隋心怡王瑞刚梁小江

电子科技 2017年1期
关键词:即时通讯序列化服务端

隋心怡,王瑞刚,梁小江

(1.西安邮电大学 物联网与两化融合研究院,陕西 西安 710061;2.陕西省信息化工程研究院,陕西 西安 710061)

基于Google Protocol Buffer的即时通讯系统设计

隋心怡1,王瑞刚1,梁小江2

(1.西安邮电大学 物联网与两化融合研究院,陕西 西安 710061;2.陕西省信息化工程研究院,陕西 西安 710061)

为提高即时通讯服务数据传输和存储的高效性和稳定性,提出了一种基于Google Protocol Buffer的即时通讯系统。该系统利用Protocol Buffer数据交换格式对通讯数据进行处理,提高系统的传输效率。实验结果表明,与json、xml相比,经Protocol Buffer序列化后的数据大小要明显小于其他两种方法,系统整体传输效率和安全性较高,并且具有良好的扩展性。

即时通讯;Protocol Buffer;序列化;数据交换格式;数据传输

即时通讯(Instant Message,IM)是一种可以让使用者在局域网或互联网上建立某种私人聊天的实时通讯服务。由于其灵活性和方便性,被越来越多地应用到日常生活中。即时通讯也对通信的稳定性提出了更高的要求[1-3]。在即时通讯中,大量数据在移动端和服务端进行频繁的交互都是需要建立在一定的数据交换格式基础上,以保证发送方和接收方能够按照约定的方式传输数据[4-7]。

Google提出的Protocol Buffer是一种基于二进制的数据传输格式,在数据传输过程中可以高效地压缩数据,不仅使数据传输量减少,同时也加快了数据的压缩速率,从而进一步提高数据传输的效率和响应速度[8-11]。

1 Google Protocol Buffer

1.1 简介

Protocol Buffer是Google公司开发的一种混合语言数据标准,主要应用在结构化数据的描述、传输和存储几个方面。Protobuf(Protocol Buffer)将数据结构对象转换成二进制数据流的形式进行存储,可以简单的实现数据流与对象之间的转换[12-13]。

开发人员按照一定的语法定义结构化的消息格式,然后发送给命令行工具生成相关的类,以支持Java、C++、Python等语言环境。将这些生成类引入到系统项目中,整个系统可以直接调用相关方法完成业务消息的序列化和反序列化[14-15]。

1.2 应用场景

Protobuf作为一种兼容性较好、高效率的二进制数据传输格式,多用于分布式应用之间的数据通信或异构环境下的数据交换,包括网络传输、数据存储、配置文件等领域。

在实际开发中,不同语言的前后端在交互时不可直接调用。为保证通讯的即时性,服务端随时可能下发数据到客户端,客户端同时主动向服务端发送请求。这种交互的实现要求必须基于确定的协议来规定数据格式,也就是说,在服务器与客户端交互时,需要将准备传输的内容按照规定模式转化为一种中间语言(Byte数组),然后在另一端根据同样的格式转换回原来语言的对象。开发者使用Protobuf作为数据交换格式,可以方便地定义业务传输协议,高效、简单地完成数据交换。通过Protobuf在开发时不再需要关注通信协议中的编码解码工作,而更多的专注于业务处理上。

1.3 编码设计

Protobuf在功能上与xml类似,但是经过序列化后的数据更小,所以解析数据速率更快。其序列化后的Byte数组简洁紧凑,编解码速度快,而且占用的空间也少。与xml相比,Protocol序列化之后的数据量约为xml的1/3~1/10。

整个消息以二进制流的方式存储,在这个二进制流中,逐个字段以定义的顺序紧紧相邻,每个字段中由元信息tag和字段的值value组成。图1所示为序列化编码示意图。

图1 Protocol Buffer序列化编码示意图

解码程序读入二进制的字节流进行解码时,通过引用消息的类型定义决定解析的字段名字和声明类型。

1.4 实现过程

Protobuf采用二进制形式对数据进行描述,编程人员只需要使用其描述一次数据结构,便可以满足跨平台的、不同语言之间的结构化的读写。

实现过程如下:

(1) 编写协议文件.proto,在协议文件中定义需要做串行化的数据结构信息。定义的每个文件都属于一个面向对象的集合,集合中先写入数据类型再写Protobuf数据,其中包含着消息体的各种属性和逻辑关系;

(2) 通过protoc编译器的命令行生成所选择语言的特定类。生成的代码中定义了操作消息属性的各个方法,根据属性的不同生成包括set()、get()等函数,且每个生成的类里都会有序列化和反序列化的方法,这些方法用于转化当前数据为流数据发送或从流数据解析数据;

(3) 服务端和客户端分别调用生成类。此处同调用普通的类库一样,通过message接口提供的ParseFrom()方法从输入流中读取二进制的编码消息再解释成message对象便可以直接操作。

2 即时通讯中Protobuf的实现

2.1 即时通讯概况

即时通讯系统一般分为客户端和服务器端,采用典型的分布式客户/服务器结构,服务器提供消息服务,客户端是用户代理,之间通过一定的协议进行交互。要使用户可以在Android、iOS平台下进行文本消息、文件等形式的即时通讯功能,总体需求架构如图2所示。

图2 即时通讯需求架构

根据系统架构及功能需求,包括用户登录、消息传输等所有交互的请求及回应都有相应的消息格式。Protocol Buffer应用于即时通讯系统中,需要先构建对应.proto的消息数据文件,通过编译器编译后生成对应的所需语言的数据类和接口。

2.2 Protocol Buffer定义及通信格式设计

整个系统定义一个枚举消息,其中包含系统所用到的所有模块的消息序号

enum Modle{

logininfo = 1; //用户登录信息

login_res = 2; //用户登录响应

msginfo = 3; //消息传送信息

msg_res = 4; //消息传送响应

fileinfo = 5; //文件传输信息

file_res = 6; //文件传输响应

… …

}

在整个即时通讯系统中,包括用户登陆、消息传送等每个服务模块都是和请求应答相对应的,同时为每一个具有消息体的消息定义一个对应的Protobuf message,以用户登录为例构建login.proto文件,其中登录请求logininfo消息结构化定义具体如下

message logininfo{

required string login_name = 1;

required string passwd = 2;

enum UserStat{

online = 1;

leave = 2;

}

optional UserStat type = 3[default = online];

optional int32 version = 4;

}

logininfo消息包含的login_name、passwd、type、version字段分别表示用户登录时的用户名、密码、登录状态以及客户端版本。其中required修饰的字段表示登录名、密码这些信息是必不可少的;定义UserStat枚举用户不同的登录状态,包括用户在线和离线状态,也属于logininfo信息的一部分,同时要定义type字段调用枚举UserStat的值用以表示用户登录的不同状态,和version一样用optional修饰表示该字段可选,即用户信息中不一定要有用户状态和客户端版本信息。

网络传输过程中数据需要按照一定的格式组成固定的结构。Protobuf将数据进行序列化后,使用TCP/IP进行网络传输时,需要对所有的数据传输单元做粘包、拆包处理,而传输的message并未对消息长度做出定义,接收方不能做出相应解析。要保证通信的正常进行,传输数据中需要包含除原始数据本身之外的数据说明信息以及与数据交换相关的描述性信息。设计固定的通信格式,将序列化后获得的消息嵌入到另外一个二进制信息中,以确保接收方从传输数据中提取出相应的数据进行解析。

为便于数据的编解码操作,本文定义一种通信格式,在数据发送之前对原始数据添加消息头封装成传输数据单元。消息头需要包含包括数据长度、服务号在内的几种字段主要设计。

图3 数据交换格式

前4位Length 标识出原始数据的长度;Protocol打包的数据没有自带长度而不能直接对消息进行切分,发送数据前计算发送数据的大小并存储到前4 Byte空间中,接收数据时解析消息头可以获得原始数据的大小,取消息头之后指定大小的数据进行解析;

Module表示消息类型,在消息头占2 Byte;解码后根据Module字段可以知道要处理的消息属于哪个模块,将任务派发到相应业务模块的处理函数以完成相应的业务过程;

Array 占整个消息头的后2 Byte,用以判断传输数据的大小端;由于跨平台的网络数据交换需要进行字节序转换,通信双方需要达成一致的规则以保证交流的信息单元是以正确的顺序被传送。

2.3 调用机制

对已经定义好的结构化消息通过Protobuf的编译器protoc生成特定的类,命令如下

protoc --java_out=. login.proto

protoc --cpp_out=. login.proto

protoc -python_out=.login.proto

运行以上命令在.proto文件所在目录下生成相应的Java、C++和Python的数据类和接口代码。Protocol编译器会为每一个message生成一个类,其中包含基本函数、消息实现、嵌套类型、访问器等部分内容。

本次实验调用生成的C++语言相关代码,可以直接在服务端引用生成文件login.pb.cc和login.pb.h中的类。引入生成文件到工程中可以像使用自定义类一样初始化相应数据类型,对Modlue中每一个枚举的消息都会特化一个process方法。

客户端在与服务端进行数据交互之前,网关要对消息头中的字段进行初始化,然后调用Protobuf提供的编码方法将原始数据结构化成二进制数据流,并将数据写入队列数据结构的请求队列中,添加初始化之后的数据长度等字段,封装成数据传输单元后发送至服务端;服务端接收后对其进行分包解析,提取消息头中的说明信息后调用Protobuf的解码方法反序列化请求包,同时向客户端返回数据接收成功的确认完成数据传输过程。

3 Protobuf应用于即时通讯系统优点

3.1 提高传输效率

Protobuf传输数据较json、xml速率均有所提升。随机测试一组数据经程序处理后,得出Protobuf、json和xml序列化之后的数据统计如表1所示。

表1 数据结果统计

选取中间4组数据绘制成折线对比图,如图4所示。

图4 数据折线对比图

通过数据对比测试可以得出以下结论:随着原始数据的增加,Protobuf序列化之后的数据始终是最小的;在原始数据逐步增大时,Protobuf与xml、json比较其优势也相对减少。

结合日常使用情况可以得知,IM软件的移动端用户更习惯于用少于100字(约500 Byte)的文本信息交流,Protocol较json、xml序列化在该条件下优势较为明显。故采用Protocol作为即时通讯系统中的数据交换格式可以在大多数情况下提升系统性能。

3.2 易于扩展

在实际应用中,系统功能需要经常性升级,可以通过在.proto文件中增加新的message字段实现。Protobuf提供了很好的兼容性,不必破坏已部署的、依靠老数据格式的程序就可以对数据结构进行升级。

在对协议扩展时要求遵守必要的规则,包括不能修改现有的tag number、不能添加和删除required字段、添加或删除optional和repeated字段并使用新的tag number。遵守这些规则,原代码可以正确读取新的message,但会忽略新的字段;对于删除optional的字段,原码会使用其默认值;对于删除的repeated字段,则将其置空。Protobuf良好的向后兼容性可以保证系统功能的正常运行。

3.3 安全性

Protobuf对外部类的成员变量仅提供了getter()方法,而没有提供set方法为成员变量赋值,对所有外部类的赋值操作都需要通过builder类来执行,赋值完成后将builder类成员的值赋给外部类的对应对象。一旦数据构建完成将不能再对其进行修改,保证了数据传输的安全性。

4 结束语

通过引入Google Protocol Buffer的数据结构和序

列化方法,设计了完整的数据传输协议将数据结构封装到数据传输单元,完成了即时通讯系统中客户端和服务端的数据传输过程。

本文主要根据对Protobuf协议的分析结果讨论即时通讯系统框架,整体框架仍需要按照实际需求进行继续完善。通过研究测试,Protobuf的引入确实给即时通讯系统的设计和实现在系统效率及安全性等方面带来较大的提高。

[1] 聂晓旭,于凤芹,钦道理. 基于 Protobuf 的数据传输协议[J].计 算 机 系 统 应 用,2015,24(8):112-116.

[2] 殷昊,沈奇威,王纯.Protocol Buffer在Android企业云通讯录中的应用[J].电信科学,2012(9):148-151.

[3] 李纪欣,王康,周立发,等.Google Protobuf在Linux Socket通讯中的应用[J].电脑开发与应用,2013(4):1-5.

[4] 宫唐小恒,李旭伟. Protocol Buffers:比XML快近100倍[J].电脑与信息技术,2009(1):65-68.

[5] 窦进叶.基于Protocol Buffers的企业即时通讯应用的研究和实现[D].青岛:中国海洋大学,2014.

[6] 李毅成,梁涛. 即时通讯软件的协议设计[J]. 办公自动化杂志,2008(143):38-39.

[7] 刘青. 基于 Protocol Buffer 的即时通信监控系统设计与实现[D].武汉:华中科技大学,2013.

[8] Google.Protocol buffers[EB/OL]. (2008- 07- 09)[2015-12-12]http://code.google.com/apis/pro Toc Olbuffers/docs/overview.html.

[9] Google. Protobuf for developers[EB/OL].(2010-03-02)[2015-12-10] https://developers.google.com/protocol-buffers/docs/overview.

[10] Feng Jianhua. Google protocol buffers research and application in online game[J]. IEEE Network, 2011, 7(11):625-627.

[11] 黎二荣.移动云计算环境下即时通讯框架的研究与实现[D].北京:中国地质大学,2014.

[12] 宋瑾.基于ProtocolBuffer 协议的服务端-客户端通信[J].电脑编程技巧与维护,2014,12(47):100-101.

[13] 史栋杰.五种快速序列化框架的性能比较[J].电脑知识与技术,2010,11(34):9710-9712.

[14] 王少林,李祥明,李永刚.基于 Protocol Buffers 的航天测控数据交换模式研究[J].遥测遥控,2012, 6(33):55-60.

[15] 朱浩悦,侯敏.基于Android的移动即时通讯系统的设计与实现[J].电脑知识与技术,2015, 11(34):106-107.

A Design of Instant Message System based on Google Protocol Buffer

SUI Xinyi1,WANG Ruigang1,LIANG Xiaojiang2

(1. Institute of IOT&IT-based Industrialization,Xi’an University of Posts and Telecommunications,Xi’an 710061,China ;2. Institute of Communication Technology, Xi’an 710061,China)

In view of improving the efficiency and stability of the data transmission and storage in instant messaging service,an instant messaging system based on Google Protocol Buffer is proposed.This pager put Protocol buffers data-exchange format in processing communication data,increasing the efficiency of data transmission.Experimental results show that the data size after Buffer Protocol serialization is significantly less than JSON or XML.Transmission efficiency and security is relatively high and has a good expansibility.

instant messaging;Protocol Buffer;serialize;data-exchange format;data transmission

2016- 03- 25

隋心怡(1992-),女,硕士研究生。研究方向:移动互联网。王瑞刚(1966-),男,高级工程师。研究方向:多媒体通信领域。梁小江(1983-),男,工程师。研究方向:云计算与大数据处理。

10.16180/j.cnki.issn1007-7820.2017.01.033

TN919.6;TP302.1

A

1007-7820(2017)01-119-04

猜你喜欢

即时通讯序列化服务端
如何建构序列化阅读教学
云存储中基于相似性的客户-服务端双端数据去重方法
新时期《移动Web服务端开发》课程教学改革的研究
民事诉讼中即时通讯记录的证据采用进路
在Windows Server 2008上创建应用
即时通讯软件发展模型的实证研究
Java 反序列化漏洞研究
科学技术哲学视域下的即时通讯
即时通讯软件WhatsApp
作文训练微格化、序列化初探