*** 序: ***
IM 中的数据通信协议指的是 IM 系统中应用层所使用的通信协议,该通信协议的设计效果会对 IM 系统的流量消耗、电量消耗、通信速度、兼容性、可扩展性等方面均会造成一定的影响,所以一般的 IM 系统均需要根据自身的业务场景和需求选择恰当的通信协议或制定最优性能的通信协议。
影响数据通信协议选择的因素
-
**网络数据大小 **:占用带宽,传输效率。尽量不要有冗余数据,这样才能够少占用带宽,少占用资源,少网络 IO,提高传输效率。
-
** 网络数据安全性 **:敏感数据的网络安全。必须考虑对部分有安全性要求的传输数据进行加密。在银行等数据安全性要求很高的应用行业和场景里尤为重要,当然传统的即时通讯应用里基于用户隐私考虑,数据加密也同样是个必须考虑的问题。安全性是应用的基础条件,需求是一样的,只是加密程度、安全性级别要求有不同而已。
-
** 编码复杂度 **:编码复杂度包括序列化和反序列化复杂度、效率、数据结构的可扩展性和可维护性。对于平台相关业务的代码实现也需要考虑到数据发送方和数据接收方数据处理的复杂度和数据结构的可扩展性,可维护性,人力成本和实施复杂度等。
-
** 协议通用性、大众规范 **:数据类型必须是跨平台的,数据格式是通用的;
-
** 可扩展性 **:方便覆盖各类业务;
-
** 节省电量和流量消耗 **:移动端业务尤为重要。
** 总结 **:一个好的数据通信协议一般需要具备如下条件:高效,简洁,可读性好,节约流量,节省电量,易于拓展,同时又能够匹配当前团队的技术堆栈。
数据通信协议类型
应用层通信协议主要有文本协议和二进制协议。
-
** 文本协议:**
文本协议即采用最符合人类表达习惯的文本语言进行数据传输的协议,如 Http 1.x 采用的便是文本协议。IM中,MSN使用的是文本协议。特点:
- 可读性比较好,调试方便;
- 可通过 key:value 键值对进行扩展,扩展性比较好;
- 需要一行一行对键值对进行解析,所以解析效率比较低;
- 对语音、视频等二进制格式的支持不是很好;
-
** 二进制协议:**
二进制协议即数据传输通过二进制流进行传输的协议,如 Http/2、IP 协议等。二进制协议一般由定长包头和可扩展变长包体组成,协议规范中对每个字段的含义进行了相应的规定。QQ 使用的是二进制协议。
特点:
- 可读性差,调试不太方便;
- 可扩展性差,扩展字段时,新旧版本兼容性差;
- 解析效率高;
常见通信协议分析
- ** XMPP:**
XMPP(Extensible Messaging and Presence Protocol,可扩展通讯和表示协议),是一个基于 XML 的协议,主要用于即时消息以及在线现场探测。
优点:协议成熟,强大,可扩展性强,基于 XML 语言,可读性好,在各个端(包括服务器) 有各种语言的实现,开发者接入方便,目前主要应用于许多聊天系统中,且已有开源的Java 版的开发实例 androidpn。
缺点:协议较复杂,冗余(基于XML),流量和电量消耗不容小觑,部署硬件成本高,XML 解析代价高。
-
** SIP:**
SIP(Session Initiation Protocol,会话初始协议),是一个基于文本的应用层控制协议,用于创建、修改和释放一个或多个参与者的会话,多用于 VoIP(Voice Over Internet Protocol)相关的模块。优点:
- SIP 电话基于现在的因特网系统,接入方便、覆盖面广,需要的设备也非常简单;
- IP 电信业能够提供多样化的通信服务,如:电话到电话、电脑到电话、传真到传真等。SIP 是一 种 IP 电信业务,应用方式灵活,功能丰富;
- VoIP的通话质量比较好。传统语音通话采用的是模拟信号技术,模拟信号容易受到干扰,且传统电话一般采用的是高失真压缩技术,很难避免信号失真,而VoIP采用的是数字传输技术,在网络上传输的是包含语音信息的数据包,可以进行低失真压缩,这些数据包只要被对方收到并按约定的规则还原为语音信号,失真度一般都比较小。
-
** Protobuf:**
Protobuf 是 Google 开源的一个序列化框架,类似于 XML、JSON等,该框架在易用性、数据大小及效率方面进行了良好的平衡处理。一条消息经 Protobuf 序列化后的数据只有二进制数据的 1/10、XML格式的1/20、JSON的1/10,数据量大幅缩小。优点:
- 灵活:方便接口更新;
- 高效:效率经过 Google 优化,传输效率比普通 XML 等高许多;
非常小、非常快、非常简单,一条消息数据用Protobuf序列化后的大小是JSON的1/10、XML格式的1/20、是二进制序列化的1/10。 - 易于使用:开发人员通过按照一定的语法定义结构化的消息格式,然后送给命令行工具,工具将自动生成相关的类,可以支持java、c++、python等语言环境。通过将这些类包含在项目中,可以很轻松的调用相关方法来完成业务消息的序列化与反序列化工作;
- 支持的语言丰富:原生支持c++、java、python等多达10余种语言。
缺点:不能表示复杂的数据结构,但是对于IM来讲,已经足够。
适用场景:
- 需要和其它系统进行消息交换的场景;
- 对消息 Size 很敏感的场景;
- 小数据场景,大数据场景下不是很适合;
- 项目语言是 C++、Java、Python 等,这几类语言可以使用 Google 的源生类库,序列化和反序列化效率非常高。其它的语言需要第三方或者自己写,序列化和反序列化的效率不保证。
-
** MQTT:**
MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是IBM开发的一个即时通讯协议,是一个基于代理的发布/订阅模式的轻量级消息传输协议,它可以通过很少的代码和带宽与远程设备连接。特点:
- 使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合;
- 对负载内容屏蔽的消息传输;
- 使用 TCP/IP 提供网络连接;
- 有三种消息发布服务质量:至少一次、至多一次、只有一次;
- 小型传输,开销很小(固定长度的头部是2字节),协议交换最小化,以降低网络流量;
优点:协议简洁轻巧,数据冗余量低,流量消耗小,电量消耗小,可扩展性好,支持的设备从智能硬件到智能手机无所不包;
缺点:它并不是一个专门为 IM 设计的协议,多使用于推送;服务器端实现难度大,虽然已经有了 C++ 版本的服务端组件,但是并不开源;数据量较大时的并发处理难度大。
-
** 私有协议 :**
市面上几乎所有主流 IM APP 都是是使用私有协议,一个被良好设计的私有协议优势非常明显。优点:高效,节约流量(一般使用二进制协议),安全性高,难以破解;
缺点:工作量大,在开发初期没有现有样列可以参考,需要考虑全面,容易出错,对于设计者的要求比较高;编码复杂度高(自己定义消息格式,自己编写序列化和反序列化方法,自己进行容错处理等),可扩展性不强(比如添加个字段,就必须改两端的逻辑处理)。
私有协议的设计
- ** 序列化与反序列化 **
移动互联网相对于有线网络最大特点是:** 带宽低、延迟高、丢包率高、稳定性差、流量费用高 **。所以在私有协议的序列化上一般使用二进制协议,而不是文本协议。常见的二进制序列化库有 Protobuf 和 MessagePack,也可以自己定制私有的二进制协议序列化和反序列的过程,比如蘑菇街的TeamTalk。一般,Protobuf 和 MessagePack 的可扩展性和可读性较自定义的序列化过程要好很多,所以大部分情况下不推荐自己实现二进制协议的序列化和反序列化过程。
- ** 协议格式设计 **
基于 TCP 的应用层协议一般都分为包头和包体(如 HTTP),IM 协议也不例外。包头一般用于表示每个请求/反馈的公共部分,如包长、请求类型、返回码等。 而包体则填充不同请求/反馈对应的信息。
网友评论