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

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

时间: 2024-09-28 17:09:33

移动端IM开发需要面对的技术问题的相关文章

前端学习---移动端vue开发踩坑记

前言: 大概两个月前投身于一个项目中去,项目是一个移动端的项目,所选用的框架是时下比较流行的vue.这篇文章也是针对这个项目和以前自己学习时的一些总结,包括一些通用的移动端开发要注意的事项.vue开发遇到的一些问题.本文的目的是为了在以后的开发中我们可以避免这些坑,提高我们的开发效率. 一.移动端开发特有问题: 1.移动端样式的兼容性: 在当前移动端的开发要面对各种不同的手机,不同的手机DPI也是不同的,比如Iphone 8的DPI就是2,Iphone 8P的DPI就是3.为了让页面可以兼容不同

端游开发中用什么技术可以让用户更短时间内体验游戏?端游分发

网络游戏是很多人日常娱乐的主要方式之一,尤其是近几年来游戏产业的发展可以说是一片欣欣向荣,虽然手游的发展势头越来越好,但是端游在体验上确实有其不可替代性,而且用户群体也更稳定用户忠诚度也更高.不过端游的一般都很大,即使使用了P2P的下载方式好的网络条件下也需要2-3个小时,甚至更长时间.不过小编发现,在玩游戏的过程中经常会遇到以下现象: 每每打开游戏或是正在游戏时,总会时不时的弹出建议使用游戏加速器的提示框,点击之后的确发现游戏更流畅了,那么这到底是怎么实现的呢?是因为使用了CDN加速吗?除了这

移动端前端开发概述

1 移动端开发的背景 1.全球移动端设备将会超过人口总数: 2.移动端上网时间超过pc端上网时间: 3.平板电脑.电子阅读器.智能电视和手机等设备每天下载数以百万计的应用 .     总结: 面对这样的挑战,让头脑与目光保持一定的前瞻性是很重要的. 要想使自己的产品在占有率及收入等方面取得持续性的成功,产品设计与开发的策略必须符合移动应用的未来发展趋势. 2 移动端开发和pc端开发的异同 2.1 性能差异 这是最显著的一个差异.对移动开发影响最大的,就是性能问题,特别是功耗和流畅性问题. 2.2

移动端Web开发调试之Chrome远程调试(Remote Debugging)

本篇主要说一下Chrome RemoteDebugging 的方法,之前也遇到一些坑,自己总结了一些经验,分享如下. Chrome DevTools调试移动设备Brower Page Tabs/WebViews 安卓远程调试目前支持所有操作系统(Windows,Mac, Linux, and Chrome OS.)中调试,支持: ● 调试站点的页面 ● 调试安卓原生App中的WebView ● 实时将安卓设备的屏幕图像同步显示到开发机器. ● 通过端口转发(port forwarding)与虚拟

移动端web开发常见问题

上一篇总结了一些有关html5和css3的面试题,这一篇是有关于移动端web开发的常见问题,希望一样对你有一些帮助. Meta相关 1. 添加到主屏后的标题(IOS) <meta name="apple-mobile-web-app-title" content="标题"> 2. 启用 WebApp 全屏模式(IOS) 当网站添加到主屏幕后再点击进行启动时,可隐藏地址栏(从浏览器跳转或输入链接进入并没有此效果) <meta name="a

移动端跨平台开发干货分享

(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 第一次推荐国内技术专家的文章,涉及的是移动端跨平台开发的话题. 之前NativeScript 1.0发布的时候,就打算谈谈移动端跨平台开发这个话题.正好,今天国内技术专家"吴多益"发表了一篇文章<聊聊移动端跨平台开发的各种技术>就这个话题,给大家分享了很多干货. 为什么大家对移动端跨平台开发总是孜孜不倦的追求,各种框架也是层出不穷呢?究其原因,还是由于纯HTML在手机

论移动端Hybid开发

以下内容code地址:https://github.com/wytings/Hybrid 背景:公司业务的发展和开发需求升级,我们需要Hybrid了.市面上有很多开源的Hybrid框架给我们直接使用,但是经过一段时间的尝试与研究,我司最终选择自己开发一套相对简洁的Hybrid框架.很多人会疑惑,为什么还要造轮子?因为我们觉得这些"轮子",并不是很适合我们,我们评估后,觉得再造一个"轮子"反倒成本更低. 前言:我们应该要时刻注意到不要让自己的开发被新技术所引导或者迷惑

学习JavaWeb项目开发需要掌握的技术

武汉java培训学习JavaWeb项目开发需要掌握的技术,国内外信息化建设已经进入基于Web应用为核心的阶段, java作为应用于网络的最好语言,前景无限看好.然而,就算用Java建造一个不是很烦琐的web应用,也不是件轻松的事情.概括一下,实施Java的WEB项目需要掌握的技术如下:Java语言面向对象分析设计思想设计模式和框架结构XML语言网页脚本语言数据库应用服务器集成开发环境下面我们具体地看每个技术.1.Java语言Java语言体系比较庞大,包括多个模块.从WEB项目应用角度讲有JSP.

移动端前端开发调试

转自:http://yujiangshui.com/multidevice-frontend-debug/ 通过移动端使用 Web 服务的比率越来越大,例如淘宝今年双十一,移动端交易份额就达到 42.6%.由此可见,掌握移动端的前端开发和测试是非常有必要的. 由于之前做过大量有响应式需求的项目:今年(2014)年初也配合 Denis 的 微信机器人 做了一些用于微信的移动端项目:在淘宝 UED 实习的时候,也有参与过一个针对移动端的游戏的部分开发.所以算是积累了一点移动端调试的经验,在这里分享一