im通讯用什么协议 详细解析im通讯协议

本文要讨论的IM通信协议是指应用层通信的“语言”,而不是传输层协议(如TCP、UDP)。IM通信协议的制定是IM开发的起点,也是贯穿设计、开发、运行和维护的核心。通信协议的设计直

本文最后更新时间:  2023-03-26 16:32:57

本文要讨论的IM通信协议是指应用层通信的“语言”,而不是传输层协议(如TCP、UDP)。IM通信协议的制定是IM开发的起点,也是贯穿设计、开发、运行和维护的核心。通信协议的设计直接影响到用户体验(数据流量、功耗、通信速度)、兼容性(新老版本无缝融合)、可扩展性(后期版本如何升级)等等,是一项基础性的、极其重要的工作。
本文将通过理论与实践相结合的方式,详细解释一个典型IM的通信协议设计的各个方面。
本文原作者为58同城网沈剑:58同城技术委员会主席,高级架构师,优秀讲师。原百度hi团队成员,负责58同城im系统架构设计。

IM通信协议的层次化设计


所谓“协议”,就是双方共同遵守的规则,比如离婚协议、停战协议等。
协议有三个元素:语法、语义和时间:

(1)语法:即数据与控制信息的结构或格式(2)语义:即需要发出何种控制信息,完成何种动作以及做出何种响应(3)时序:即事件实现顺序的详细说明


典型的IM通信协议设计分为三层:应用层、安全层和传输层。

即时消息应用层协议设计


应用层协议有三种常见类型:文本协议、二进制协议和流式XML协议。

1.文本协议


文本协议是指“接近人类书面语言表达”的通信传输协议。典型的协议是http协议。http协议看起来像这样:

1234GET / HTTP/1.1User-Agent: curlHost: musicml.netAccept: */*


文本协议的特征是:

a. 可读性好,便于调试b. 扩展性也好(通过key:value扩展)c. 解析效率一般(一行一行读入,按照冒号分割,解析key和value)d. 对二进制的支持不好 ,比如语音/视频

在IM中,MSN使用文本协议。

2.二元协议


二进制协议是指二进制协议,典型的是ip协议。下面是ip协议的一个示例:


二进制协议一般有定长头和可扩展的变长头,每个字段都有固定的含义。例如,IP协议的前四位表示协议版本号(详见TCP/IP详解第3章)。
二进制协议有一些特点:

a. 可读性差,难于调试b. 扩展性不好 ,如果要扩展字段,旧版协议就不兼容了,所以一般设计时会有一个Version字段c. 解析效率超高(几乎没有解析代价)d. 对二进制的支持不好 ,比如语音/视频

IM,QQ使用时间二进制协议。

3.流式XML协议


xmpp,im的准标准协议,使用流XML,比如gtalk。学校里的这些IM都是基于xmpp的。我们来看一个xmpp协议的例子:


1234567 <message to = '[URL = mailto:Romeo @ example . net]Romeo @ example . net[/URL]' from = '[URL = mailto:Juliet @ example . com]Juliet @ example . com[/URL]' type = ' chat ' XML:lang = ' en ' >& ltbody & gt你在哪里,罗密欧?& lt/body >& lt/message >


从xml标签可以大致判断这是罗密欧发给朱丽叶的聊天信息。Xmpp协议可以实现跨域互操作。比如gtalk和学校里的用户聊天。只要在服务器端实现s2s服务(server to server),现在im基本没有互通需求,所以这个服务基本没有人实现。
XMPP协议有几个特点:

a.它是准标准协议,可以跨域互通b.XML的优点,可读性好,扩展性好c.解析代价超高(dom解析)d.有效数据传输率超低(大量的标签)


个人强烈不建议使用xmpp,尤其是无线im。如果要用,必须自己压缩,减少网络流量(用过xmpp的同学都知道,发一个登录包需要多少交互,浪费多少流量)。

4.实际例子


让我们来看一个im协议的实际例子。常见的做法是:定长二进制包头,可扩展变长包体。包可以使用可扩展的协议,如文本和XML。包头负责传输和解析效率,与业务无关。包保证可伸缩性,与业务相关。
这是一个实际的16字节im二进制定长头:


123456789//sizeof(cs _ essay-header)= 16 struct cs _ essay-header { uint 32 _ t version;uint32 _ t magic _ numuint32 _ t cmduint32 _ t lenuint 8 _ t data[];}__attribute__((打包));


–a.前4个字节是版本;;
–b.接下来的四个字节是一个“幻数(magic_num)”,用来保证数据错位或者丢包。通常的做法是在报头中加入一些约定的特殊字符,在包的末尾加入一些约定的特殊字符。发送给您的协议,几个字节的位置,是0x 01020304。
–c.接下来是command(命令号),用于区分keepalive报文、业务报文、密钥交换报文等。
–d.len(数据包长度),它告诉服务器应该在多长时间内收到数据包。
这是一个实际的可扩展im变长包:


123456789 message CUserLoginReq {可选字符串username = 1;可选字符串passwd = 2;}message CUserLoginResp{可选uint 64 uid = 1;}


用的是google的Protobuf协议(玩过的都能看懂)。如您所见,登录请求包传输用户名和密码,登录响应包返回用户的uid。当然,除了Protobuf,还有xml、json、mcpack(你懂吗?)等等。
立场鲜明的推荐Protobuf。主要有几个原因:

a. 现成的解析库种类多,可以生成C++、Java、php等10余种语言代码(详见请点b. 自带压缩功能c. 在工业界已广泛应用d. google制造

IM安全层协议设计


im协议,消息的保密性很重要,谁都不希望自己的聊天内容被看到,所以安全层必不可少。

1使用SSL
证书管理有点复杂,而且成本很高。2自加解密
自加解密的核心在于密钥的生成和管理。密钥管理的方式有很多种,主要有三种:(1)固定密钥
服务器和客户端同时约定一个密钥和一个加密算法(如:AES)。每次发送客户端im之前,通过这种方式,密钥和算法对程序员是透明的。(2)一个人一把钥匙
简单来说,每个人的钥匙都是固定的,只是彼此不同。其实固定密钥的算法包含了用户的一些特殊属性,比如用户uid、手机号、qq号等。(3)动态密钥(一个会话一个密钥)
动态密钥,一个会话一个密钥更安全,每次会话前协商密钥。密钥协商的过程必须经历两次随机生成非对称密钥和一次随机生成对称加密密钥。这里不讨论细节,有兴趣的同学可以看看SSL密钥协商的过程。IM传输层协议设计


可选协议是TCP和UDP。现在IM传输层基本都用TCP。有了epoll等技术,多连接不是瓶颈,几十万个单机链接也没有问题。58同城在线单机连接现在好像是10w?(可能单机性能测试能达到一百万,一般在线跑到几十万)
关于QQ使用UDP的问题。我个人不知道QQ使用UPD作为传输层协议的初衷,但我的猜测是10多年前客户端10K的问题没有得到很好的解决,一台服务器无法支持1W的TCP连接。腾讯同时在线流量高,没办法只能用UDP,但是UDP不可靠,只能在UDP上实现TCP超时/重传/确认机制。

标签

【/br/】关于QQ使用UDP协议,在讨论过程中,有同学提出了一个非常好的问题:“无线环境下,UDP比较好,可以独立于状态,而TCP不稳定,进出电梯就会断线,用户体验不好”。
实际上,“用户状态可以被设计成独立于连接状态”。如果你有兴趣,我可以写一篇文章以后和你聊天。传输层使用TCP,那么如何让在线状态独立于底层连接。

温馨提示:内容均由网友自行发布提供,仅用于学习交流,如有版权问题,请联系我们。