移动端IM开发需要面对的技术问题

标签: 移动 im 开发 | 发表时间:2016-08-09 10:08 | 作者:
出处:http://www.iteye.com

1、前言

这两年多一直从事网易云信 iOS 端 IM SDK的开发,期间不断有兄弟部门的同事和合作伙伴过来问各种技术细节,干脆统一介绍下一个IM APP的方方面面,包括技术选型(包括通讯方式,网络连接方式,协议选择)和常见问题。(原文链接: http://www.52im.net/thread-133-1-1.html

分享者:项望烽,毕业于浙江大学,目前是网易云信 iOS 端研发负责人。 

2、学习交流

- 即时通讯开发交流群:   215891622 [推荐]

- 移动端IM开发推荐文章:《 新手入门一篇就够:从零开发移动端IM

3、P2P还是服务器中转?

IM通讯方式无非两种选择:设备直连(P2P)和通过服务器中转。

3.1 P2P方式

P2P多见于局域网内聊天工具,典型的应用有:飞鸽传书、天网Maze(你懂的)等。这类软件在启动后一般做两件事情:

  • 进行UDP广播:发送自己信息和接受同局域网内其他端信息;
  • 开启TCP监听:等待其他端进行连接。

详细的流程可以参考飞鸽传书源码。但是这种方式在有种种限制和不便:一方面它只适合在线的点对点消息传输,对离线,群组等业务支持不够。另一方面由于 NAT 的存在,使得不同局域网内机器互联难度大大上升,在某些网络类型(对称NAT)下无法建立连接。

3.2 服务器中转方式

几乎所有互联网IM产品都采用服务器中转这种方式进行消息传输,相对于P2P的方式,它有如下的优点:

  • 能够支持更多P2P无法支持或支持不好的业务,如离线消息,群组,聊天室服务;
  • 方便业务逻辑的拓展和新旧版本的兼容。

当然它也有自己的问题:服务器架构复杂,并发要求高。

4、该选择什么样的网络通讯技术?

IM主流网络通讯技术有两种:

  • 基于TCP的长连接;
  • 基于HTTP短连接PULL的方式。

后者常见于WEB IM系统(当然现在很多WEB IM都是基于WebSocket实现),它的优点是实现简单,方便开发上手,问题是流量大,服务器负载较大,消息及时性无法很好地保证,对大规模的用户量支持不够,比较适合小型的IM系统,如小网站的客户系统。

基于TCP长连接则能够更好地支持大批量用户,问题是客户端和服务器的实现比较复杂。当然也还有一些变种,如下行使用MQTT进行服务器通知/消息的下发,上行使用HTTP短连接进行指令和消息的上传。这种方式能够保证下行消息/指令的及时性,但是在弱网络下上行慢的问题还是比较严重。早期的来往就是基于这种方式。

5、协议如何制定?

IM协议选择原则一般是:易于拓展,方便覆盖各种业务逻辑,同时又比较节约流量。后一点的需求在移动端IM上尤其重要。常见的协议有:XMPP、SIP、MQTT、私有协议。(更多关于即时通讯应用的协议选择,请参见《如何选择即时通讯应用的数据传输格式》: http://www.52im.net/thread-276-1-1.html

5.1 XMPP

优点:协议开源,可拓展性强,在各个端(包括服务器)有各种语言的实现,开发者接入方便;
缺点:缺点也是不少,XML表现力弱、有太多冗余信息、流量大,实际使用时有大量天坑。

5.2 SIP

SIP协议多用于VOIP相关的模块,是一种文本协议,由于我并没有实际用过,所以不做评论,但从它是文本协议这一点几乎可以断定它的流量不会小。

5.3 MQTT

优点:协议简单,流量少;
缺点:它并不是一个专门为IM设计的协议,多使用于推送。

5.4 私有协议

市面上几乎所有主流IM APP都是是使用私有协议,一个被良好设计的私有协议优点非常明显。

优点:高效,节约流量(一般使用二进制协议),安全性高,难以破解;
缺点:在开发初期没有现有样列可以参考,对于设计者的要求比较高。

5.5 结论

一个好的协议需要满足如下条件:高效,简洁,可读性好,节约流量,易于拓展,同时又能够匹配当前团队的技术堆栈。基于如上原则,我们可以得出: 如果团队小,团队技术在IM上积累不够可以考虑使用XMPP或者MQTT+HTTP短连接的实现。反之可以考虑自己设计和实现私有协议。

6、该如何设计私有通信协议?

6.1 序列化与反序列化

移动互联网相对于有线网络最大特点是:带宽低,延迟高,丢包率高和稳定性差,流量费用高。所以在私有协议的序列化上一般使用二进制协议,而不是文本协议。

常见的二进制序列化库有protobuf和MessagePack,当然你也可以自己实现自己的二进制协议序列化和反序列的过程,比如蘑菇街的TeamTalk。但是前面二者无论是可拓展性还是可读性都完爆TeamTalk(TeamTalk连Variant都不支持,一个int传输时固定占用4个字节),所以大部分情况下还是不推荐自己去实现二进制协议的序列化和反序列化过程。

6.2 协议格式设计

基于TCP的应用层协议一般都分为包头和包体(如HTTP),IM协议也不例外。包头一般用于表示每个请求/反馈的公共部分,如包长,请求类型,返回码等。 而包头则填充不同请求/反馈对应的信息。

一个最简单的包头可以定义为:

1
2
3
4
5
6
7
struct  PackHeader
{
     int32_t     length_;    //包长度
     int32_t     serial_;    //包序列号
     int32_t     command_;   //包请求类型
     int32_t     code_;      //返回码
};


以心跳包为例,假设当前的serial为1,心跳包的command为10,那么使用MessagePack做序列化时:length=4,serial=1,command=10,code=0,每个字段各占一个字节,包体为空,仅需要4个字节。

当然这是最简单的一个例子,面对真正的业务逻辑时,包体里面会需要塞入更多地信息,这个需要开发根据自己的业务逻辑总结公共部分,如为了兼容加入的协议版本号,为了负载均衡加入的模块id等。

7、其他不可忽视的问题

上面的内容就是一个IM系统大致的选型过程:服务方式,网络通讯协议,数据通信协议选择、协议设计。但是实际开发过程中还有大量的问题需要处理。

7.1 协议加密

为了保证协议不容易被破解,市面上几乎所有主流IM都会对协议进行加密传输。常见的流程和HTTPS加密相似:建立连接后,客户端和服务器进行进行协商,最终客户端获得一个当前Sessino的秘钥,后续的数据传输都通过这个秘钥进行加解密。一般出于效率的考虑都会采用流式加密,如RC4。而前期协商过程则推荐使用RSA等非对称加密以增加破解难度。

7.2 快速连接(即掉线重连机制)

对iOS APP而言,因为没有真后台的存在,APP每次启动基本都需要一次重连登录(短时间内切换除外),所以如何快速重连、重登就非常重要。
常见优化思路如下:

  • 本地缓存服务器IP并定期刷新。移动网络调优可以参考《 iOS端移动网络调优的8条建议》;
  • 合并部分请求。如加密和登录操作可以合并为同一个操作,这样就可以减少一次不必要的网络请求来回的时间;
  • 简化登录后的同步请求,部分同步请求可以推迟到UI操作时进行,如群成员信息刷新。 

7.3 连接保持(即心跳机制)

一般APP实现连接保持的方式无非是采用应用层的心跳,通过心跳包的超时和其他条件(网络切换)来执行重连操作。那么问题来了:为什么要使用应用层心跳和如何设计应用层心跳。众所周知TCP协议是有KEEPALIVE这个设置选项,设置为KEEPALIVE后,客户端每隔N秒(默认是7200s)会向服务器发送一个发送心跳包。

但实际操作中我们更多的是使用应用层心跳。原因如下:

  • KEEPALIVE对服务器负载压力比较大(服务器大大是这么说的...);
  • socks代理对KEEPALIVE并不支持;
  • 部分复杂情况下KEEPALIVE会失效,如路由器挂掉,网线(移动端没有网线...)直接被拔除。

移动端在实际操作时为了节约流量和电量一般会在心跳包上做一些小优化:

  • 精简心跳包,保证一个心跳包大小在10字节之内;
  • 心跳包只在空闲时发送;
  • 根据APP前后台状态调整心跳包间隔 (主要是安卓)。

7.4 消息可达(即QoS机制)

在移动网络下,丢包,网络重连等情况非常之多,为了保证消息的可达,一般需要做消息回执和重发机制。参考易信,每条消息会最多会有3次重发,超时时间为15秒,同时在发送之前会检测当前连接状态,如果当前连接并没有正确建立,缓存消息且定时检查(每隔2秒检查一次,检查15次)。所以一条消息在最差的情况下会有2分钟左右的重试时间,以保证消息的可达。

因为重发的存在,接受端偶尔会收到重复消息,这种情况下就需要接收端进行去重。通用的做法是每条消息都戴上自己唯一的message id(一般是uuid)。

7.5 文件上传优化

IM消息(包括SNS模块)内包含大量的文件上传的需求,如何优化文件的上传就成了一个比较大的主题。

常见有下面这些优化思路:

  • 将上传流程提前:音频提供边录边传。朋友圈的图片进行预上传,选择图片后用户一般会进行文本输入,在这段时间内后台就可以默默将选好的图片进行上传;
  • 提供闪电上传的方式:服务器根据MD5进行文件去重;
  • 优化和上传服务器的连接(参考快速连接),提供连接重用的功能;
  • 文件分块上传:因为移动网络丢包严重,将文件分块上传可以使得一个分组包含合理数量的TCP包,使得重试概率下降,重试代价变小,更容易上传到服务器;
  • 在分包的前提下支持上传的pipeline,避免不必要的网络等待时间;
  • 支持断点续传。

(原文链接: http://www.52im.net/thread-133-1-1.html

更多IM技术文章

[1] 网络编程基础资料:
TCP/IP详解 -  第11章·UDP:用户数据报协议
TCP/IP详解 -  第17章·TCP:传输控制协议
TCP/IP详解 -  第18章·TCP连接的建立与终止
TCP/IP详解 -  第21章·TCP的超时与重传
理论经典:TCP协议的3次握手与4次挥手过程详解
理论联系实际:Wireshark抓包分析TCP 3次握手、4次挥手过程
计算机网络通讯协议关系图(中文珍藏版)
NAT详解:基本原理、穿越技术(P2P打洞)、端口老化等
UDP中一个包的大小最大能多大?
Java新一代网络编程模型AIO原理及Linux系统AIO介绍
NIO框架入门(三):iOS与MINA2、Netty4的跨平台UDP双向通信实战
NIO框架入门(四):Android与MINA2、Netty4的跨平台UDP双向通信实战
>>  更多同类文章 ……

[2] 有关IM/推送的通信格式、协议的选择:
为什么QQ用的是UDP协议而不是TCP协议?
移动端即时通讯协议选择:UDP还是TCP?
如何选择即时通讯应用的数据传输格式
强列建议将Protobuf作为你的即时通讯应用数据传输格式
移动端IM开发需要面对的技术问题(含通信协议选择)
简述移动端IM开发的那些坑:架构设计、通信协议和客户端
理论联系实际:一套典型的IM通信协议设计详解
58到家实时消息系统的协议设计等技术实践分享
>>  更多同类文章 ……

[3] 有关IM/推送的心跳保活处理:
Android进程保活详解:一篇文章解决你的所有疑问
Android端消息推送总结:实现原理、心跳保活、遇到的问题等
为何基于TCP协议的移动端IM仍然需要心跳保活机制?
微信团队原创分享:Android版微信后台保活实战分享(进程保活篇)
微信团队原创分享:Android版微信后台保活实战分享(网络保活篇)
移动端IM实践:实现Android版微信的智能心跳机制
移动端IM实践:WhatsApp、Line、微信的心跳策略分析
>>  更多同类文章 ……

[4] 有关WEB端即时通讯开发:
新手入门贴:史上最全Web端即时通讯技术原理详解
Web端即时通讯技术盘点:短轮询、Comet、Websocket、SSE
SSE技术详解:一种全新的HTML5服务器推送事件技术
Comet技术详解:基于HTTP长连接的Web端实时通信技术
WebSocket详解(一):初步认识WebSocket技术
socket.io实现消息推送的一点实践及思路
>>  更多同类文章 ……

[5] 有关IM架构设计:
浅谈IM系统的架构设计
简述移动端IM开发的那些坑:架构设计、通信协议和客户端
一套原创分布式即时通讯(IM)系统理论架构方案
从零到卓越:京东客服即时通讯系统的技术架构演进历程
蘑菇街即时通讯/IM服务器开发之架构选择
腾讯QQ1.4亿在线用户的技术挑战和架构演进之路PPT
微信技术总监谈架构:微信之道——大道至简(演讲全文)
如何解读《微信技术总监谈架构:微信之道——大道至简》
快速裂变:见证微信强大后台架构从0到1的演进历程(一)
17年的实践:腾讯海量产品的技术方法论
>>  更多同类文章 ……

[6] 有关IM安全的文章:
即时通讯安全篇(一):正确地理解和使用Android端加密算法
即时通讯安全篇(二):探讨组合加密算法在IM中的应用
即时通讯安全篇(三):常用加解密算法与通讯安全讲解
即时通讯安全篇(四):实例分析Android中密钥硬编码的风险
传输层安全协议SSL/TLS的Java平台实现简介和Demo演示
理论联系实际:一套典型的IM通信协议设计详解(含安全层设计)
微信新一代通信安全解决方案:基于TLS1.3的MMTLS详解
来自阿里OpenIM:打造安全可靠即时通讯服务的技术实践分享
>>  更多同类文章 ……

[7] 有关实时音视频开发:
即时通讯音视频开发(一):视频编解码之理论概述
即时通讯音视频开发(二):视频编解码之数字视频介绍
即时通讯音视频开发(三):视频编解码之编码基础
即时通讯音视频开发(四):视频编解码之预测技术介绍
即时通讯音视频开发(五):认识主流视频编码技术H.264
即时通讯音视频开发(六):如何开始音频编解码技术的学习
即时通讯音视频开发(七):音频基础及编码原理入门
即时通讯音视频开发(八):常见的实时语音通讯编码标准
即时通讯音视频开发(九):实时语音通讯的回音及回音消除概述
即时通讯音视频开发(十):实时语音通讯的回音消除技术详解
即时通讯音视频开发(十一):实时语音通讯丢包补偿技术详解
即时通讯音视频开发(十二):多人实时音视频聊天架构探讨
即时通讯音视频开发(十三):实时视频编码H.264的特点与优势
即时通讯音视频开发(十四):实时音视频数据传输协议介绍
即时通讯音视频开发(十五):聊聊P2P与实时音视频的应用情况
即时通讯音视频开发(十六):移动端实时音视频开发的几个建议
即时通讯音视频开发(十七):视频编码H.264、V8的前世今生
简述开源实时音视频技术WebRTC的优缺点
良心分享:WebRTC 零基础开发者教程(中文)
>>  更多同类文章 ……

[8] IM开发综合文章:
移动端IM开发需要面对的技术问题
开发IM是自己设计协议用字节流好还是字符流好?
请问有人知道语音留言聊天的主流实现方式吗?
IM系统中如何保证消息的可靠投递(即QoS机制)
谈谈移动端 IM 开发中登录请求的优化
完全自已开发的IM该如何设计“失败重试”机制?
微信对网络影响的技术试验及分析(论文全文)
即时通讯系统的原理、技术和应用(技术论文)
开源IM工程“蘑菇街TeamTalk”的现状:一场有始无终的开源秀
>>  更多同类文章 …… 

[9] 开源移动端IM技术框架资料:
开源移动端IM技术框架MobileIMSDK:快速入门
开源移动端IM技术框架MobileIMSDK:常见问题解答
开源移动端IM技术框架MobileIMSDK:压力测试报告
>>  更多同类文章 ……

[10] 有关推送技术的文章:
iOS的推送服务APNs详解:设计思路、技术原理及缺陷等
Android端消息推送总结:实现原理、心跳保活、遇到的问题等
扫盲贴:认识MQTT通信协议
一个基于MQTT通信协议的完整Android推送Demo
求教android消息推送:GCM、XMPP、MQTT三种方案的优劣
移动端实时消息推送技术浅析
扫盲贴:浅谈iOS和Android后台实时消息推送的原理和区别
绝对干货:基于Netty实现海量接入的推送服务技术要点
移动端IM实践:谷歌消息推送服务(GCM)研究(来自微信)
为何微信、QQ这样的IM工具不使用GCM服务推送消息?
>>  更多同类文章 ……

[11] 更多即时通讯技术好文分类:

  http://www.52im.net/forum.php?mod=collection&op=all

作者: Jack Jiang (点击作者姓名进入Github) 
出处: http://www.52im.net/space-uid-1.html 
交流:



已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [移动 im 开发] 推荐:

移动端IM开发需要面对的技术问题

- - ITeye博客
这两年多一直从事网易云信 iOS 端 IM SDK的开发,期间不断有兄弟部门的同事和合作伙伴过来问各种技术细节,干脆统一介绍下一个IM APP的方方面面,包括技术选型(包括通讯方式,网络连接方式,协议选择)和常见问题. 分享者:项望烽,毕业于浙江大学,目前是网易云信 iOS 端研发负责人. - 移动端IM开发推荐文章:《.

三大运营商到齐 移动IM市场变数陡增

- Yu - cnBeta.COM
号称“短信杀手”的类Kik应用正打着“免费、省流量”的旗号攻城略地,也获得了互联网大佬们的青睐,给手机IM(即时通讯)领域带来了新的变数. “米聊、微信、口信、有你”,互联网大佬们扎堆推出相应的应用产品,也牵动了运营商的敏感神经.

电信运营商移动IM产品集体失策

- chris - 月光博客
  大型电信运营企业在应对移动互联网通信工具时“集体失策”,这样的论断,或许对运营商的移动IM战略和产品规划人员不公平. 凭心而论,沃友、飞聊和翼聊,这些产品本身做得还不错,并且思路也非常开放,尤其是决策自己开展互联网通信业务,和竞争对手一起蚕食基础电信业务的份额,对三大运营商而言,走出这一步,需要相当大的魄力.

Miranda IM v0.9.28 Final 多国语言版

- 阳阳 - 饭堂 - 『新软速递』
Miranda IM是一个多协议的即时通讯客户端软件. 它运行时仅占用极少的内存,并且不需要安装,解压后即可运行. 这使得用户可以从可移动的存储设备上运行他们的即时通讯客户端程序. 如果仅使用少量的插件,它甚至可以被放到一张软盘里. 强大的插件使得Miranda IM拥有极好的可扩展性. 只有基本的功能是内置的,其余的功能需要通过插件来实现.

新浪微博的IM战略

- 董玉伟 - 36氪
7月中旬我们曾独家透露了新版新浪微博的界面,并从新版界面中看到,用户已经有在线和离线的状态显示,同一天,新浪微博正式发布微博桌面,宣布微博支持即时聊天,我们都以为,新浪要开始在 IM 领域再次发力,与腾讯 QQ 竞争. 今天在跟新浪微博开放平台一位产品经理聊天时,他向我们透露说,新浪微博的 IM 并非是为了跟 QQ 抢市场.

三大电信商激战语音IM

- 小熊TONY - cnBeta.COM
在米聊、微信吸引人们眼球的同时,三大电信运营商已经不约而同地将触角伸到了这场语音即时通信(IM)软件的激战中. 昨天,正在进行中的2011年中国国际通信展上,中国移动相关人士称,移动新版的即时通信软件“飞聊”于今天正式对外发布,届时可在飞信官网下载. 据悉,首先发布的是针对安卓、塞班两大平台的产品,苹果iOS版将下个月推出,均为公测版.

手机IM:谁动了谁的奶酪

- 小熊TONY - cnBeta.COM
国内类Kik应用的迅猛发展,给手机IM领域带来新的变数. 微信、米聊、推信、飞聊……国内类Kik应用层出不穷. 号称“短信杀手”的类Kik应用打着“免费、省流量”的旗号,攻城略地,据悉,腾讯微信的用户规模已经达到1500万,而小米科技的米聊也俘获了500万的用户.

来自蘑菇街的开源IM:TeamTalk

- - 标点符
TeamTalk 是蘑菇街开源的一款企业办公即时通信软件,最初是为自己内部沟通而做的 IM 工具. 麻雀虽小五脏俱全,本项目涉及到多个平台、多种语言,简单关系如下图:. CppServer:TTCppServer工程,包括IM消息服务器、http服务器、文件传输服务器、文件存储服务器、登陆服务器. Java DB Proxy:TTJavaServer工程,承载着后台消息存储、redis等接口.

QQ是IM附带微博功能,”微博桌面”是微博附带IM功能

- 談何容易 - 36氪
有一天我问一朋友,为啥腾讯微博还不出桌面客户端. 他愣了一下,然后我突然想到,腾讯微博为啥要出桌面客户端,它已经集成到了QQ上,QQ是一个IM工具,但现在它附带了微博的功能. 不到一个月前,新浪推出了微博桌面,支持即时聊天,当时大家就说,新浪要开始抢腾讯的饭碗了. 最近,微博桌面进行改版升级,我只能说,它更像 QQ 了.

移动开发那些事

- - 微博UDC
说实话,我们这次开发移动端的项目,整个项目组的人都是第一次,最初立项的时候为是选择native app和web app还争论了一番,最后综合考虑,我们选择了web(我们选择了h5)开发. 但从这两种开发模式的特点来说,从它们诞生之日起就开始了不断的争论,孰好孰坏,本文不作探讨,只是简单罗列下本人开发遇到的问题和最终的解决方案.