前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >移动互联网IM之协议设计

移动互联网IM之协议设计

作者头像
MelonTeam
发布于 2018-01-04 09:55:06
发布于 2018-01-04 09:55:06
4.1K10
代码可运行
举报
文章被收录于专栏:MelonTeam专栏MelonTeam专栏
运行总次数:0
代码可运行

导语:如果想自己动手实现一个移动互联网IM app,要怎么做?第一个要解决的问题就是IM协议的设计。本文将讲述如何从0到1设计一个私有的tcp协议。

虽然现在市面上已经存在各种各样的消息推送SDK如信鸽,但可能由于各种原因无法全面满足需求,还是想自己实现一个IM或推送功能。那么你需要解决哪些问题呢?首先面临的第一个问题就是如何实现IM协议?

传输协议选择

传输协议一般是指TCP和UDP协议。UDP协议是无连接的,面向消息的,主要提供高效率服务。它的效率高,占资源少,但是其传输不可靠,只管发送,不管对方是否收到,虽然可以通过其他手段来实现可靠性。TCP是面向连接的,面向流的,主要提供可靠性服务。可靠性正是IM最需要的特性,所以现在主流IM基本都是使用TCP协议实现的。      

关于PC QQ仍然在使用UDP的问题,经过私下了解是由于历史原因,所以一直沿用到现在。笔者猜测应该是因为当年C10K问题没有得到很好的解决,因为TCP是面向连接的,当时还没有epoll技术的存在,无法很好地解决同时在线的高负载问题,所以只能使用UDP了,因为UDP是无连接的,没有负载问题,但UDP又不可靠,所以只能在UDP上实现TCP的超时、重传、确认等机制。

协议格式选择

常见的TCP协议格式通常有3种:文本协议、二进制协议、XML协议。

文本协议

文本协议一般是由一串ACSII字符组成的数据。文本协议容易被人类解读,比较适合面向公众,典型的如HTTP协议。举一个HTTP GET的例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
GET /HTTP/1.1
User-Agent: curl
Host: qq.com
Accept: */*

文本协议的特点: a. 可读性好,便于开发调试; b. 扩展性好,key-value扩展容易; c. 解析效率较好; d. 流量较小。        

曾经一方霸主的IM产品MSN使用的是就是文本协议。

XML协议

主流IM协议之一XMPP就是一种以XML为基础的开放式实时通信协议。举一个XMPP发送消息的例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<message from="sendinguser@somedomain" to="recipient@somedomain" xml:lang='en'>
  <body>
    Body of message
  </body>
</message> 

XML协议的特点: a. 继承了XML的优点,可读性好,扩展性好; b. 解析代价较高,效率低,占用资源多; c. 流量大。      

 Google出品的IM产品GTalk正是使用XMPP协议。

二进制协议

二进制协议就是一串字节流,一般包括定长的包头和可扩展变长的包体,典型的如MQTT协议。举一个二进制协议例子:

二进制协议特点: a. 可读性差,难于调试; b. 扩展性较差; c. 解析效率高,几乎没有解析代价; d. 流量占用极少。        

QQ和微信正是使用二进制的典型代表,现在市面上大部分IM产品也都是使用二进制。虽然它可读性差,难于调试,可这正也是提高协议被破解的门槛。所以对流量和电量敏感的移动互联网IM来说,二进制协议最为适合。

主流协议比较

在比对了协议格式后,我们接着比较一下各种协议标准。目前市面上主流的IM协议主要有应用于PC互联网的XMPP,嵌入式设备物联网上的MQTT,一起来看下它们之间的优缺点比较:

| 名称 | 优点 | 缺点 | | :—- |:——— | :——— | | XMPP | 基于XML协议,容易理解,使用广泛,易于扩展 | 流量大,在移动终端解析也耗电。交互过程复杂,多被pc时代的产品使用,不适合应用于移动互联网IM | | MQTT | 低带宽,适合推送,适配多平台 | 协议简单,但是需要自己扩展好友,群组等功能 | | 私有协议 | 灵活、低带宽、自主控制 | 要考虑可扩展、兼容性、序列化和反序列化、安全等问题 |

私有协议设计

基于TCP的应用层协议一般都分为包头和包体(如HTTP),IM协议也不例外。所以常见的做法是:定长二进制包头,可扩展变长包体,包体可以使用文本如Protobuf、MessagePack、JSON、XML等扩展性好的协议。包头负责传输和解析效率,是所有包的公共部分,与业务无关。包体保证扩展性,与业务相关。一个典型的二进制协议如下:

| 字段 | length | message_id | version | type | data | | :—: | :—: | :—: | :—: | :—: | :—: | | 类型 | int | int | byte | int | byte[] | | 字节数 | 4 | 4 | 1 | 4 | n |

1、length:包长度,告知服务端要接收多长的包数据;

2、message_id:消息ID,由于网络复杂性,客户端和服务端的交互消息可能无法保证必达,所以需要重发来保证,为了避免消息重复,可以使用消息的唯一标识来去重;

3、version:消息版本号,由于二进制格式扩展性不好,如果要扩展字段,旧版协议就不兼容了,所以一般会有一个version字段用于区分版本;

4、type:消息类型,用来区分不同功能的消息包,如密钥交换消息、心跳消息、业务消息、错误返回消息、推送消息等;

5、data:包体数据,业务不同,长度可变。

粘包问题

值得一提的是,由于TCP是基于流式数据传输的,所以会存在“粘包”问题,所谓“粘包”,是指在一次接收数据不能完整收到一个完整的消息包数据。举个例子,假设服务端按顺序发了3个包消息,如下图表示:

但客户端读取到的数据很可能会被分成下面几个片段:

这就是所谓的“粘包”问题,其解决办法一般有如下两种: 1、消息包头中包含表示消息包的总长度的字段(或者消息包体长度),上述举例的length正是采用该方案; 2、包尾添加特殊分隔符,例如每条报文结束都添加回车换行符(例如FTP协议)或者特定字符作为报文分隔符,接收方通过特殊分隔符切分报文,比如上述举例可以修改成如下格式: | 字段 | length | message_id | version | type | data_length | data | delmiter | | :—: | :—: | :—: | :—: | :—: | :—: | :—: | :—: | | 类型 | int | int | byte | int | int | byte[] | byte| | 字节数 | 4 | 4 | 1 | 4 | 4 | n | 1 |

其中delmiter可以固定为“@”等特殊字符,delmiter应尽量小,减少流量占用。另外由于包体可能包含分隔符,所以delmiter需要转义以防止解析错误,所以一般更为建议使用第一种方案解决“粘包”问题。

反设计

包头和包尾都包含分包分隔符:笔者过往接触到不少项目的协议都采用了这种方法来分包,通过以上“粘包”问题分析可知,这种做法只会浪费流量,不会有更多好处。

序列化选择

包体可以使用文本如Protobuf、MessagePack、JSON、XML等扩展性好的协议,但我们推荐优先考虑Protobuf,网上对序列化和反序列化的方案选择的讨论也非常多,我们这里就不再赘述,这也是目前主流IM的选择。 Protobuf优点:

  1. 标准的IDL和IDL编译器,这使得其对工程师非常友好;
  2. 序列化数据非常简洁,紧凑,序列化后的大小是json的1/10,xml格式的1/20,是二进制序列化的1/10;
  3. 解析速度非常快,比对应的XML快约20-100倍;
  4. 提供了非常友好的动态库,使用非常简介,反序列化只需要一行代码。

Protobuf适合的场景:

  1. 需要和其它系统做消息交换的,对消息大小敏感的,消息空间相对xml和json等节省很多;
  2. 小数据的场合。如果你是大数据,用它并不适合;
  3. 项目语言是c++,java,python,因为它们可以使用google原生类库,序列化和反序列化效率非常高。 所以Protobuf解析性能高,序列化后数据量相对少,非常适合应用到移动互联网IM的场景。

安全性考虑

敏感信息直接通过IM进行网络传输,所以安全层是必不可少的,一般只需要对包体进行加密,包头明文即可。换句话说,TCP协议的安全性主要可以从以下几个方面进行考虑:

使用SSL

和HTTPS一样,使用SSL安全性高,但不同的是,HTTPS是由专门机构去验证证书合法性的,而IM不可能这样做,可行的做法是把证书打包进客户端,证书更新可以随客户端升级而一起升级,或者通过协议升级。加密的交互流程就是客户端产生一个对称的密钥,并通过证书加密后请求交给服务器,服务器解密后获得这个对称密钥,后续的通讯就全部使用这个对称的密钥来加解密,具体原理请参考SSL,这里不再赘述。不过证书成本稍高和管理稍复杂,代价较高。

自己加解密

自己实现加解密,重点在于密钥的生成与管理,密钥管理方式主要有这么两种:

1) 固定密钥    

服务端和客户端约定好一个密钥,同时约定好一个对称加密算法如AES,每次客户端发送消息前,使用约定好的算法和密钥对消息进行加密,服务端收到报文后,使用约定好的算法和密钥进行解密。这种方式优点是实现比较简单,但缺点也很明显,约定好的密钥和算法存在客户端,存在被反编译破解的风险,该方案比较适合对加密要求不高的场景;

2) 动态密钥

由于固定密钥容易暴露,所以动态密钥的理念就是对固定密钥再加一层保护。和SSL密钥协商过程类似,动态密钥的中心思想就是客户端和服务器通过非对称RSA加解密(增加破解难度)进行协商,最终客户端获得一个当前session的密钥,后续的数据传输都通过这个密钥进行AES对称加解密。流程比较复杂,具体如下图所示:

公钥请求:

1、客户端携带帐号发起请求;

2、服务端根据帐号生成对应的RSA公、私钥;

3、服务端下发公钥,保留私钥;

4、服务端返回RSA公钥给客户端,客户端保存RSA公钥;

登录鉴权: 1、客户端使用RSA公钥对帐号和密码等价物(帐号密码按一定规则编码)进行RSA非对称加密,然后携带这个加密结果发起请求; 2、服务端使用RSA私钥解密,获得帐号和密码; 3、服务端验证帐号和密码是否正确; 4、服务端给客户端分配当前session的密钥session_key; 5、服务端返回经过AES加密的session密钥session key,AES的密钥为帐号/密码等价物。后续请求都使用session_key作为密钥进行加解密。

非登录请求:

1、客户端使用session_key作为密钥对请求进行AES对称加密,发起请求;

2、服务端使用session_key对请求进行AES解密;

3、根据请求处理业务逻辑;

4、服务端使用session_key作为密钥对处理结果进行AES加密,返回给客户端。    

 终上所述,文章主要阐述了移动互联网IM的协议设计会面临的主要包括传输协议、协议格式、协议设计、协议序列化、协议安全等问题,以及对应的解决方案,这些是笔者对过往项目的总结和思考。在身处微信和QQ两大主流移动互联网IM压力下,该文章确有班门弄斧之嫌,如有不足或错误,还请各路IM大神指教:)        值得一提的是,文章的思考也将同样也适用于其他使用tcp长连接的场景,如物联网、手游等。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-03-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
1 条评论
热度
最新
信鸽产品已下线,另一款推送产品——腾讯移动推送 可以提供更优质的服务。「腾讯云移动推送 TPNS」相比「信鸽产品」的主要区别:1、信鸽推送共享30万条/秒,TPNS推送独享高速通道30万条/秒,更快,更稳定2、信鸽仅支持华为、小米、魅族、FCM厂商通道,TPNS支持华为、小米、魅族、OPPO、vivo、FCM、ROG,覆盖更多机型,更高抵达率3、信鸽共享存储空间,TPNS支持App级数据隔离,且符合GDPR规范,可支持出海业务,更安全4、TPNS更有多样化推送能力(如定时、定速、循环推送;按设备、账号、标签推送;用户分群、A/B test等),精准推送,有效提升推送效果,进入腾讯移动推送 TPNS 产品文档查看更多操作指引 https://cloud.tencent.com/document/product/548/37240?from=13828
信鸽产品已下线,另一款推送产品——腾讯移动推送 可以提供更优质的服务。「腾讯云移动推送 TPNS」相比「信鸽产品」的主要区别:1、信鸽推送共享30万条/秒,TPNS推送独享高速通道30万条/秒,更快,更稳定2、信鸽仅支持华为、小米、魅族、FCM厂商通道,TPNS支持华为、小米、魅族、OPPO、vivo、FCM、ROG,覆盖更多机型,更高抵达率3、信鸽共享存储空间,TPNS支持App级数据隔离,且符合GDPR规范,可支持出海业务,更安全4、TPNS更有多样化推送能力(如定时、定速、循环推送;按设备、账号、标签推送;用户分群、A/B test等),精准推送,有效提升推送效果,进入腾讯移动推送 TPNS 产品文档查看更多操作指引 https://cloud.tencent.com/document/product/548/37240?from=13828
回复回复点赞举报
推荐阅读
编辑精选文章
换一批
im协议设计选型(上)
im协议设计选型(上) 周末在一个Qcon群里分享了一些im技术,抽取出其中im协议选型相关的内容,跟大家分享。 分享人:58沈剑,58同城技术委员会主席,高级架构师,优秀讲师。前百度hi团队成员,负责过58同城im系统的架构设计。 一、im协议的分层设计 所谓“协议”是双方共同遵守的规则,例如:离婚协议,停战协议。协议有语法、语义、时序三要素。 (1)语法:即数据与控制信息的结构或格式 (2)语义:即需要发出何种控制信息,完成何种动作以及做出何种响应 (3)时序:即事件实现顺序的详细说明 今天的重点是在“
架构师之路
2018/03/01
1.3K0
im协议设计选型(上)
谁家的加密密钥,写死在代码里?(说的就是你)
系统设计,协议先行。 大部分人不了解协议的设计细节,更多使用已有协议进行应用层设计,例如: (1)使用HTTP,设计 get/post/cookie 参数,以及json包格式; (2)使用dubbo,而不用去深究内部的二进制包头包体细节; 无论如何,了解协议设计的原则,对深入理解系统通信非常有帮助。 一、协议的分层设计 所谓“协议”,是双方共同遵守的规则,例如:离婚协议,停战协议。协议有语法、语义、时序三要素: (1)语法,即数据与控制信息的结构或格式; (2)语义,即需要发出何种控制信息,完成何种动作以
架构师之路
2022/06/29
5600
谁家的加密密钥,写死在代码里?(说的就是你)
如何设计一款高性能的即时聊天服务
本系列将带大家从零开始搭建一个轻量级的IM服务端,麻雀虽小,五脏俱全,我们搭建的IM服务端实现以下功能:
DeROy
2021/12/13
1.4K0
如何设计一款高性能的即时聊天服务
应用层/安全层/传输层如何进行协议选型?
系统设计,协议先行。 大部分技术人没有接触协议的设计细节,更多的是使用已有协议进行应用层的编码,例如: (1)使用http作为载体,设计get/post/cookie参数 (2)使用dubbo框架,而不用去深究内部的二进制包头包体,以及序列号反序列化的细节 无论如何,了解协议设计的原则,对深入理解系统通信非常有帮助。今天就以即时通讯(后称im)为例,讲讲应用层的协议选型。 一、im协议的分层设计 所谓“协议”是双方共同遵守的规则,例如:离婚协议,停战协议。协议有语法、语义、时序三要素。 (1)语法:即数据与
架构师之路
2018/03/01
1.4K0
应用层/安全层/传输层如何进行协议选型?
移动端IM开发需要面对的技术问题
P2P多见于局域网内聊天工具,典型的应用有:飞鸽传书、天网Maze(你懂的)等。这类软件在启动后一般做两件事情:
JackJiang
2018/08/23
1.3K0
Https详解+wireshark抓包演示
在说HTTPS之前先说说什么是HTTP,HTTP就是我们平时浏览网页时候使用的一种协议。HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传输隐私信息非常不安全。为了保证这些隐私数据能加密传输,于是网景公司设计了SSL(Secure Sockets Layer)协议用于对HTTP协议传输的数据进行加密,从而就诞生了HTTPS。SSL目前的版本是3.0,被IETF(Internet Engineering Task Force)定义在RFC 6101中,之后IETF对SSL 3.0进行了升级,于是出现了TLS(Transport Layer Security) 1.0,定义在RFC 2246。实际上我们现在的HTTPS都是用的TLS协议,但是由于SSL出现的时间比较早,并且依旧被现在浏览器所支持,因此SSL依然是HTTPS的代名词,但无论是TLS还是SSL都是上个世纪的事情,SSL最后一个版本是3.0,今后TLS将会继承SSL优良血统继续为我们进行加密服务。目前TLS的版本是1.2。
用户2929716
2018/08/23
3.8K0
Https详解+wireshark抓包演示
移动互联网信息传输安全现状分析
这是 2017 年 3 月份有关移动市场的统计数据,移动 app 的数量已经突破 10 亿。移动安全也成为了一个全民关注的问题。从最初的 app 只针对功能实现,爆出来了一系列的高危漏洞之后,应运而生了包括移动 app 检测、app 加固保护等工作来保护开发者以及使用者权益。同时,http 的明文数据传输问题也得到了有效解决。我们本篇文章的讨论内容还是从数据传输过程中所引发的一系列安全问题。
信安之路
2019/08/20
1.6K0
移动互联网信息传输安全现状分析
让互联网更快:新一代QUIC协议在腾讯的技术实践分享
如果:你的 App,在不需要任何修改的情况下就能提升 15% 以上的访问速度,特别是弱网络的时候能够提升 20% 以上的访问速度。
JackJiang
2018/08/29
2.6K0
协议设计
在计算机体系中,存在着很多的网络通信协议;通信协议的实际上就是一段数据,通信双方按照提前约定的规则去进行编码解码,达到传输数据的目的;例如,TCP/IP是目前计算机设备最常用的通信协议;TCP/IP实际上是一个协议族,包含一组协议,其中靠近应用层且最常用的协议是TCP和UDP。
为为为什么
2024/07/31
1430
游戏开发 —— 协议设计
语义:解释控制信息每个部分的意义。它规定了需要发出何种控制信息,以及完成的动作与做出什么样的响应。
芋道源码
2018/07/31
2.1K0
游戏开发 —— 协议设计
移动APP的IM后台架构浅析
IM(InstantMessaging 即时通讯)作为一项基础功能,很多APP都有,比如:手机QQ、微信、易信、钉钉、飞信、旺旺、咚咚、陌陌等。而IM如同我们日常生活中的水和电一样,必不可少,也是很多“社交”类APP必不可少的基础功能,而上面这些APP里面,微信最为出色。
meteoric
2018/11/20
2.3K0
详解 HTTP2.0 及 HTTPS 协议
众所周知, HTTP协议是没有安全加密的协议,因为使用明文传输,所以使用HTTP协议的站点很容易会被窃听、篡改,劫持;而伴随着互联网的发展,网络上承载了越来越多也越来越重要的数据,金融,商业,支付,机密数据等等,数据安全的重要性越来越凸显,越来越多的网站通过启用HTTPS来保障web数据传输的安全性。此外,HTTP2.0 作为新一代的WEB协议,以重量级的新特性带来更好,性能更高的web服务体验。本文基于运维视角在阐述解析HTTP2.0协议相比较HTTP1.1的优点的同时讲述HTTPS协议的原理,并结合实际业务场景作为案例,目的是可以通过本文掌握HTTP2.0及HTTPS协议,了解原理,具备定位排查问题,调优的能力。
玖柒的小窝
2021/11/28
4.2K0
详解 HTTP2.0 及 HTTPS 协议
SSL/TLS 原理及抓包详解
HTTP 本身不具备加密的功能,所以也无法做到对通信整体(使用 HTTP 协议通信的请求和响应的内容)进行加密。
因你是玫瑰色的
2022/01/04
10.3K0
用WireShark简单看看SSL/TLS协议
HTTPS目前是网站标配,否则浏览器会提示链接不安全,同HTTP相比比,HTTPS提供安全通信,具体原因是多了个“S”层,或者说SSL层[Secure Sockets Layer],现在一般都是TLS[Transport Layer Security],它是HTTP明文通信变成安全加密通信的基础,SSL/TLS介于应用层和TCP层之间,从应用层数据进行加密再传输。安全的核心就在加密上:
看书的小蜗牛
2022/05/26
2.4K0
用WireShark简单看看SSL/TLS协议
TCP网络那点破事!三次握手、四次挥手、TIME-WAIT、HTTP 2.0 ....
今天主要给各位分享TCP网络的一些常见知识点,日常工作或面试会经常遇到。考虑内容篇幅不小,建议先收藏,慢慢咀嚼。
微观技术
2021/09/15
4790
让互联网更快的协议,QUIC在腾讯的实践及性能优化
本文系由“腾讯技术工程官方号”公众号与“InfoQ”公众号合办的“腾讯技术工程”专栏第二篇文章(第一篇回顾:QQ相册后台存储架构重构与跨IDC容灾实践),新的一年,腾讯技术工程专栏将为大家提供更多的腾讯技术干货与落地实践。同时,该专栏欢迎TEGer投递优质稿件,投稿请联系RTX(alvisshao)。
腾讯技术工程官方号
2023/07/26
1.4K0
让互联网更快的协议,QUIC在腾讯的实践及性能优化
假如让你来设计SSL/TLS协议
说起网络通信协议,相信大家对 TCP 和 HTTP 都很熟悉,它们可以说是当今互联网通信的基石。但是,在网络安全方面,它们却是有着很大安全风险:
元闰子
2022/03/05
5650
假如让你来设计SSL/TLS协议
敏感数据加密方案及实现
本文首发于政采云前端团队博客:敏感数据加密方案及实现 https://www.zoo.team/article/data-encryption
政采云前端团队
2020/11/05
3.5K0
敏感数据加密方案及实现
Wireshark抓包帮你理清HTTPS请求流程
提示:本文通过wireshark抓包,详细从三次握手、TLS/SSL握手、数据传输、四次挥手详细分析每个过程,所以文章内容有点长,但是值得一看,建议收藏,慢慢看!
李俊鹏
2020/06/15
10.8K0
Wireshark抓包帮你理清HTTPS请求流程
让互联网更快的协议,QUIC 在腾讯的实践及性能优化
本文将主要介绍 QUIC 协议在腾讯内部及腾讯云上的实践和性能优化。
serena
2018/01/15
4.8K1
让互联网更快的协议,QUIC 在腾讯的实践及性能优化
相关推荐
im协议设计选型(上)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验