一、前言
IM发展至今,已是非常重要的互联网应用形态之一,尤其移动互联网时代,它正以无与论比的优势降低了沟通成本和沟通代价,对各种应用形态产生了深远影响。
做为IM开发者或即将成为IM开发者的技术人员,IM的价值和重要性不言自明。但从技术实现来说,IM系统的开发(尤其是移动端IM)还是存在许多技术难点和坑点的。也正因如此,优质的IM开发相关的资料、实践性成果,对于没有太多技术储备的新手来说,尤其难以获得。
本文将以新手的视角引导你阅读相关文章,以便为从零开发一个移动端IM做好方方面面的知识准备:包括但不限于网络编程基础、通信协议的选型、IM的架构设计等等。文笔有限,如有不妥之处还请批评指正,希望对你有用。(本文同步发布于:http://www.52im.net/thread-464-1-1.html)
二、读完本文的收获
2.1 您将获得
本文将假设你是毫无技术准备的新手,引导你通过一篇篇精选的文章,了解如何开始从零开发一个移动端IM所需要的各种技术、资料和实践性代码。
2.2 您无法获得
鉴于IM技术的复杂性,IM开发相关的技术不是一篇文章所能展现的了,限于篇幅原因本文将不包含任何实践性代码、也尽量不对某项技术作深入的展开,相关的实践性代码、资料、技术详解等请依据本文作者准备的文章逐个深入阅读和学习,而这也恰恰是本文想达到的目的。
三、题外话
随着近两年IM云服务的发展,很多团队基于种种原因,直接选择了短平快的云IM接入APP中。然而,考虑到云IM无论从商业模式还是运营模式上,还需经过多年的沉淀,才可能真正实现客户与服务商的运营和服务良性循环的双赢局面。因则,如何选择云IM服务商,这就是个头疼的问题了,不过这不是本文将要讨论的重点,如果需要,你也可以加入本文提到的讨论交流群,与大家一起交流群:215891622。
好了,以下是正文内容。
四、网络编程理论准备
4.1 UDP、TCP协议理论
我们都知道,IM系统的业务本质就是客户端与客户端进行消息的实时传递,而技术基础就是基于Socket连接的实时数据读写,那么基本的网络编程理论基础是作为新手的你必须掌握的知识点。当然,作为IM开发来说,基础的网络理论就够用了,也没有必要像网络工程师一样精通所谓的OSI七层参考模型。
如果你还不知道什么是UDP、TCP协议,请阅读以下文章:
《TCP/IP详解-第11章·UDP:用户数据报协议》
《TCP/IP详解-第17章·TCP:传输控制协议》
《TCP/IP详解-第18章·TCP连接的建立与终止》
《TCP/IP详解-第21章·TCP的超时与重传》。
这几篇文章有助于对UDP、TCP协议建立基本的认识,当然如果时间允许,能全书阅读网络编程理论经典《TCP/IP详解 卷1:协议》则再好不过了。另外,UDP、TCP作为基础计算机数据传输协议,在其之上衍生了很多应用层协议,相关的协议族关系图可以在此文中找到:《计算机网络通讯协议关系图(中文珍藏版)》,可作为您日常的备查手册使用。
4.2 深入理解TCP传输协议
透彻理解TCP传输协议的连接和断开过程非常有助于您日后IM算法的优化和实现,这个过程被形象的总结为“3次握手与4次挥手”。
以下文章有助于您深入理解之:
《理论经典:TCP协议的3次握手与4次挥手过程详解》
《理论联系实际:Wireshark抓包分析TCP 3次握手、4次挥手过程》。
4.3 深入理解UDP传输协议
相比TCP协议,UDP数据传输协议就显得非常轻量和易于理解,UDP通常被用于需要快速响应的数据传输场景下,对应于IM中的应用形态有:P2P通信、实时音视频等。另外,通常的IM都会被应用于互联网上(而非局域网),那么了解所谓的NAT路由技术原理等,也将有助于您对P2P打洞、UDP端口老化等概念有一个清楚的认知。
以下文章有助于您在接下来开发IM的实际应用中提供一定的实践依据:
《UDP中一个包的大小最大能多大?》
《NAT详解:基本原理、穿越技术(P2P打洞)、端口老化等》。
当然,现时的网络编程,为了解决高性能问题,有很多成型的Socket应用层模式存在,比如:NIO、AIO等,文章《Java新一代网络编程模型AIO原理及Linux系统AIO介绍》简单介绍了传统的阻塞式IO、NIO,并着重介绍了最新的AIO技术,如有时间您很有必要予以了解。(更多同类文章:点此进入…)
五、网络编程基础实践
如果你认真读完了上一层的文章,是时候写些代码,来理论联系实际理解Socket通信的原理和实践了。
有关TCP的Socket通信Demo文章和代码:
《Android端与服务端基于TCP协议的Socket通讯》
iOS平台的CocoaAsyncSocket托管代码中有许多TCP的官方Demo代码,值得一看。
当然,以是只是随手找的Demo代码,网络上有关TCP数据通信的演示性代码很容易找到,在此就不过多举例了。
本文作者专门编写的有关跨移动端平台的UDP Socket通信Demo:
《NIO框架入门(一):服务端基于Netty4的UDP双向通信Demo演示》
《NIO框架入门(二):服务端基于MINA2的UDP双向通信Demo演示》
《NIO框架入门(三):iOS与MINA2、Netty4的跨平台UDP双向通信实战》
《NIO框架入门(四):Android与MINA2、Netty4的跨平台UDP双向通信实战》。
六、IM到底该用UDP还是TCP协议?
好了,上面的网络编程基础掌握后,就要开始为你的IM进行传输协议选型了。说到IM该用UDP还是TCP作为传输协议,这是个颇有争议的话题,各大社区每当此问题的出现必定是大片的不同声音。
当然,UDP和TCP各有各的应用场景,作为IM来说,早期的IM因为服务端资源(服务器硬件、网络带宽等)比较昂贵且没有更好的办法来分担性能负载,所以很多时候会考虑使用UDP,这其中主要是早期的QQ为代表。
时至今日,TCP的服务端负载已经有了很好的解决方案,加之服务器资源成本的下降,目前很多IM、消息推送解决方案也都在使用TCP作为传输层协议。不过,UDP也并未排除在IM、消息推送的解决方案之外,比如:弱网络通信(包括跨国的高延迟网络环境)、物联网通信、IM中的实时音视频通信等等场景下,UDP依然是首选项。
以下文章或许有助于您对传输层协议的选型:
《为什么QQ用的是UDP协议而不是TCP协议?》
《移动端即时通讯协议选择:UDP还是TCP?》
《微信对网络影响的技术试验及分析(论文全文)》
《为何基于TCP协议的移动端IM仍然需要心跳保活机制?》。
当然,关于IM到底该选择UDP还是TCP,这是个仁者见仁智者见智的问题,没有必要过于纠结,请从您的IM整体应用场景、开发代价、部署和运营成本等方面综合考虑,相信能找到你要的答案。
七、IM的数据通信格式选型
IM应用开发的前期技术选型时,关于数据通信格式的选择,在同行的眼里,是同样是个极富争议话题。
精略分析一下,究其原因,大概在于以下几点:
[1] 可选择的协议或封装格式多种多样: 可选择的余地大:XMPP、Protobuf、JSON、私有2进制、MQTT、定格化XML、Plain text等等; [2] 同一种格式并不能适用于大多数的场景: 不同的场景有同的考虑而协议的选择往往跟这挂钩在一起的,如:移动端IM或推送用XMPP协议时,多数情况下都会被喷; [3] 开发者对所选格式有各自的偏好: 有的人或团队对某种或某几种格式有不一样的经验和技术积累,也促成了他们对某种或某几种协议的偏好。
该选什么样的数据通信格式,同样是跟你的应用场景和使用的架构方案相关联。不过,目前以作者掌握的信息看来,作为需要运行在移动设备的IM,几乎目前所有主流讨论里都不建议使用XMPP协议,具体原因就不在此展开了,下面推荐的文章里会详细为你解答原因。
以下文章会对你的IM的数据通信格式选型有所帮助:
《如何选择即时通讯应用的数据传输格式》
《强列建议将Protobuf作为你的即时通讯应用数据传输格式》
《移动端IM开发需要面对的技术问题(含通信协议选择)》
《简述移动端IM开发的那些坑:架构设计、通信协议和客户端》
《理论联系实际:一套典型的IM通信协议设计详解》
《58到家实时消息系统的协议设计等技术实践分享》
《扫盲贴:认识MQTT通信协议》。
(更多同类文章:点此查看…)
八、移动端IM的心跳保活和后台消息推送
8.1 为什么需要心跳保活?
由于移动网络的复杂性,心跳保活对于移动端IM来说显的尤为重要,加之手机省电、省流量策略的设计,如何实现心跳保活则也非常重要,文章《基于TCP协议的移动端IM仍然需要心跳保活机制》或许可以解答你的疑问。
8.2 iOS端的后台消息推送
因为iOS平台的特殊性,iOS应用一旦退到后台,应用本身是无法用代码来实现网络保活的,也就无法自行实现后台消息推送了。
以下文章将有助于你理解iOS平台的后台消息推送原理:
《iOS的推送服务APNs详解:设计思路、技术原理及缺陷等》
《扫盲贴:浅谈iOS和Android后台实时消息推送的原理和区别》。
8.3 Android端的心跳保活和后台消息推送
鉴于Android平台众所周之的分化和互不兼容问题,Android端IM在处理心跳保活和后台消息推送时,遇到了不少的麻烦。而且,由于Android应用的生命周期管理是由系统控制,因而如何保证您的IM所在进程或后台服务不被系统杀死,是实现心跳保活和后台消息推送的实现基础。
以下文章可为你的Android端IM的心跳保活和后台推送方案的设计提供参考:
《Android进程保活详解:一篇文章解决你的所有疑问》
《Android端消息推送总结:实现原理、心跳保活、遇到的问题等》
《为何基于TCP协议的移动端IM仍然需要心跳保活机制?》
《微信团队原创分享:Android版微信后台保活实战分享(进程保活篇)》
《微信团队原创分享:Android版微信后台保活实战分享(网络保活篇)》
《移动端IM实践:实现Android版微信的智能心跳机制》
《移动端IM实践:WhatsApp、Line、微信的心跳策略分析》
(更多同类文章:此进入…)
九、移动端IM系统的架构设计
IM其本质是一套消息发送与投递系统,或者说是一套网络通信系统,归根结底就是两个词:存储与转发。但一个成熟的移动端IM系统要想正常运转,涉及的内容则远不止这些,而最考验技术功底的就是服务端架构的设计与实现。
没有过IM系统开发经验的人,可能对以上观点嗤之以鼻,在此借用TeamTalk的设计者的一段话:“IM服务器开发,从功能抽象的角度看可能非常简单,可以认为是管理大量的客户端连接和在不同的客户端之间传递消息,但具体到实现细节就比较复杂了。打个不恰当的比喻,OS的功能抽象也非常简单,无非是进程间的调度和硬件资源的管理,但要是自己去实现一个,一般人也就只能呵呵了。”
我们以一个典型方案为例,首先来提炼一下一个IM系统的主要需求:包括账号、关系链、在线状态显示、消息交互(文本、图片、语音)、实时视频电话......。
要处理好上述需求,我们通常需要从以下方面进行考量从而设计出合适的架构:
如果采用可靠传输协议TCP,需要考虑到负载问题:短连接实现账号、关系链相关业务,长连接实现上线、信息推送; 后台架构的灵活性、可扩展性:支持分布式部署——把网络层、业务逻辑层、数据层分离,网络层和业务层支持负载均衡策略、数据层支持分布式存储; 客户端SDK的易用性:把网络层、数据层分离、业务逻辑层分离。
另外,一个典型的IM系统架构设计,还有以下性能方面的热点问题需要设计者重点关注:
编码角度:采用高效的网络模型,线程模型,I/O处理模型,合理的数据库设计和操作语句的优化; 垂直扩展:通过提高单服务器的硬件资源或者网络资源来提高性能; 水平扩展:通过合理的架构设计和运维方面的负载均衡策略将负载分担,有效提高性能;后期甚至可以考虑加入数据缓存层,突破IO瓶颈; 系统的高可用性:防止单点故障; 在架构设计时做到业务处理和数据的分离,从而依赖分布式的部署使得在单点故障时能保证系统可用。 对于关键独立节点可以采用双机热备技术进行切换。 数据库数据的安全性可以通过磁盘阵列的冗余配置和主备数据库来解决。
鉴于篇幅有限,架构设计方面的内容本文就不深入展开了。
以下文章将为你的移动端IM的架构设计带来一定的参考意义:
《浅谈IM系统的架构设计》
《简述移动端IM开发的那些坑:架构设计、通信协议和客户端》
《一套原创分布式即时通讯(IM)系统理论架构方案》
《从零到卓越:京东客服即时通讯系统的技术架构演进历程》
《蘑菇街即时通讯/IM服务器开发之架构选择》
《腾讯QQ1.4亿在线用户的技术挑战和架构演进之路PPT》
《微信技术总监谈架构:微信之道——大道至简(演讲全文)》
《如何解读《微信技术总监谈架构:微信之道——大道至简》》
《快速裂变:见证微信强大后台架构从0到1的演进历程(一)》
《17年的实践:腾讯海量产品的技术方法论》。
(更多同类文章:点此进入…)
十、移动端IM的通信安全
IM(尤其移动端IM)的安全性一直是开发者需要优先考虑的基础问题,如何正确地理解和使用加密技术则显的尤其重要。IM系统大都采用C/S、B/S、P2P等技术来实现即时通信的功能,软件编制没有统一的标准,使得IM系统本身存有多种安全漏洞,加上用户缺乏安全意识,导致在使用即时通信系统时出现各种安全问题。
当今的计算机密码学的主要作用有:
加密( Encryption)、认证(Authentication),鉴定(Identification) 。
加密:防止坏人获取你的数据。 认证:防止坏人修改了你的数据而你却并没有发现。 鉴权:防止坏人假冒你的身份。
这些基本概念和加密算法原理就不在此展开叙述了。
以下文章或许有助于您设计出安全的移动端IM系统:
《即时通讯安全篇(一):正确地理解和使用Android端加密算法》
《即时通讯安全篇(二):探讨组合加密算法在IM中的应用》
《即时通讯安全篇(三):常用加解密算法与通讯安全讲解》
《即时通讯安全篇(四):实例分析Android中密钥硬编码的风险》
《传输层安全协议SSL/TLS的Java平台实现简介和Demo演示》
《理论联系实际:一套典型的IM通信协议设计详解(含安全层设计)》
《微信新一代通信安全解决方案:基于TLS1.3的MMTLS详解》
《来自阿里OpenIM:打造安全可靠即时通讯服务的技术实践分享》。
(更多同类文章:点此进入…)
十一、有关IM中的实时音视频技术
IM应用中的实时音视频技术,几乎是IM开发中的最后一道高墙。原因在于:实时音视频技术 = 音视频处理技术 网络传输技术 的横向技术应用集合体,而公共互联网不是为了实时通信设计的。实时音视频技术上的实现内容主要包括:音视频的采集、编码、网络传输、解码、播放等环节。这么多项并不简单的技术应用,如果把握不当,将会在在实际开发过程中遇到一个又一个的坑。
以下文章有助于您从零理解IM的实时音视频开发的方方面面:
《即时通讯音视频开发(一):视频编解码之理论概述》
《即时通讯音视频开发(二):视频编解码之数字视频介绍》
《即时通讯音视频开发(三):视频编解码之编码基础》
《即时通讯音视频开发(四):视频编解码之预测技术介绍》
《即时通讯音视频开发(五):认识主流视频编码技术H.264》
《即时通讯音视频开发(六):如何开始音频编解码技术的学习》
《即时通讯音视频开发(七):音频基础及编码原理入门》
《即时通讯音视频开发(八):常见的实时语音通讯编码标准》
《即时通讯音视频开发(九):实时语音通讯的回音及回音消除�概述》
《即时通讯音视频开发(十):实时语音通讯的回音消除�技术详解》
《即时通讯音视频开发(十一):实时语音通讯丢包补偿技术详解》
《即时通讯音视频开发(十二):多人实时音视频聊天架构探讨》
《即时通讯音视频开发(十三):实时视频编码H.264的特点与优势》
《即时通讯音视频开发(十四):实时音视频数据传输协议介绍》
《即时通讯音视频开发(十五):聊聊P2P与实时音视频的应用情况》
《即时通讯音视频开发(十六):移动端实时音视频开发的几个建议》
《即时通讯音视频开发(十七):视频编码H.264、V8的前世今生》
《简述开源实时音视频技术WebRTC的优缺点》
《良心分享:WebRTC 零基础开发者教程(中文)》。
(更多同类文章:点此进入…)
十二、移动端IM开发的其它热点问题
移动端IM开发中还会遇到上述内容未提及的内容,以下文章或许您用的上:
《移动端IM开发需要面对的技术问题》
《开发IM是自己设计协议用字节流好还是字符流好?》
《请问有人知道语音留言聊天的主流实现方式吗?》
《IM系统中如何保证消息的可靠投递(即QoS机制)》
《谈谈移动端 IM 开发中登录请求的优化》
《完全自已开发的IM该如何设计“失败重试”机制?》
《微信对网络影响的技术试验及分析(论文全文)》
《即时通讯系统的原理、技术和应用(技术论文)》
《开源IM工程“蘑菇街TeamTalk”的现状:一场有始无终的开源秀》
>>更多同类文章 ……
附录:其它即时通讯文章
[1] 有关WEB端即时通讯开发:
《新手入门贴:史上最全Web端即时通讯技术原理详解》
《Web端即时通讯技术盘点:短轮询、Comet、Websocket、SSE》
《SSE技术详解:一种全新的HTML5服务器推送事件技术》
《Comet技术详解:基于HTTP长连接的Web端实时通信技术》
《WebSocket详解(一):初步认识WebSocket技术》
《socket.io实现消息推送的一点实践及思路》
>>更多同类文章 ……
[2] 有关推送技术的文章:
《iOS的推送服务APNs详解:设计思路、技术原理及缺陷等》
《Android端消息推送总结:实现原理、心跳保活、遇到的问题等》
《扫盲贴:认识MQTT通信协议》
《一个基于MQTT通信协议的完整Android推送Demo》
《求教android消息推送:GCM、XMPP、MQTT三种方案的优劣》
《移动端实时消息推送技术浅析》
《扫盲贴:浅谈iOS和Android后台实时消息推送的原理和区别》
《绝对干货:基于Netty实现海量接入的推送服务技术要点》
《移动端IM实践:谷歌消息推送服务(GCM)研究(来自微信)》
《为何微信、QQ这样的IM工具不使用GCM服务推送消息?》
>>更多同类文章 ……
[3] 更多即时通讯技术好文分类:
http://www.52im.net/forum.php?mod=collection&op=all
(本文同步发布于:http://www.52im.net/thread-464-1-1.html)