即时通讯IM系统开发

我于2014年开启即时通讯的开发之路 , 历经从服务端到客户端 , 从第三方到自研 , 经历过诸多的研发难题 , 都一一破解 。现将经验总结如下 , 希望对行业内从事IM开发的程序员有所帮助 。
一、基础技术选型(1)通讯方式①P2P方式
P2P方式多用于局域网内聊天 , 这种方式在有种种限制和不便 。一方面它只适合在线的点对点消息传输 , 对离线 , 群组等支持不够 。另一方面由于 NAT 的存在 , 使得不同局域网内机器互联难度大大上升 , 在某些网络类型(对称NAT)下无法建立连接 。使用P2P方式的软件在启动后一般做两件事情:
1、进行UDP广播:发送自己信息和接受同局域网内其他端信息 。
2、开启TCP监听:等待其他端进行连接 。
②服务器中转方式
大部分的互联网IM产品都采用服务器中转这种方式进行消息传输 , 相对于P2P的方式 , 具有有以下的优点:
1、支持更多P2P无法支持或支持不好的业务 , 如离线消息 , 群组 , 聊天室 。
2、方便业务逻辑的拓展和新旧版本的兼容 , 当然它也有自己的问题 , 就是服务器架构复杂 , 并发要求高 。
通过以上的比较 , 建议我们在开发IM系统的时候使用服务器中转的方式 。
 
(2)网络连接方式IM的网络连接方式有基于TCP的长连接和基于HTTP短连接两种:
①基于TCP的长连接
基于TCP长连接则能够更好地支持大批量用户 , 问题是客户端和服务器的实现比较复杂 。也有一些改进 , 比如下行使用MQTT进行服务器通知/消息的下发 , 上行使用HTTP短连接进行指令和消息的上传 。这种方式能够保证下行消息/指令的及时性 , 但是在弱网络下上行慢的问题还是比较严重 , 早期的来往就是基于这种方式 。
②基于HTTP短连接
常见于WEB IM系统(现在很多WEBIM都是基于WebSocket实现) , 它的优点是实现简单 , 方便开发上手 , 问题是流量大 , 服务器负载较大 , 消息及时性无法很好地保证 , 对大规模的用户量支持不够 , 适合小型的IM系统 。
(3)通讯协议方式IM常见的协议有:XMPP , MQTT , 私有协议 。各种协议优缺点情况如下:
①XMPP协议
优点:协议开源 , 可拓展性强 , 在各个端(有各种语言的实现 , 对于前期入门级的开发者是很好的选择 , 方便进入IM开发的程序员快速上手 。
缺点:XML表现力弱 , 有太多冗余信息 , 流量大 。
常见案例:Gtalk、新浪微博、Facebook 。
②MQTT协议
优点:协议简单 , 流量少 。
缺点:不是一个专门为IM设计的协议 , 多使用于推送 。
③私有协议
几乎所有主流的IM App都是使用私有协议 。
优点:高效 , 节约流量(一般使用二进制协议) , 安全性高 , 难以破解 。
缺点:开发初期没有现有样列可以参考 , 对于参与IM开发的程序员的要求比较高 。
常见案例:微信、钉钉 。
根据以上的对比 , 我们得出结果 , 一个好的协议需要满足高效、简洁、节约流量、易于拓展等要求 , 同时又能够和当前的开发团队的技术堆栈匹配 , 不能选择一个他们很难上手的 。
这里再提一下 , 我当时开发IM系统的时候 , 上手用的是XMPP , 在使用的过程中发现了很多问题 , 踩了很多坑 。
二、IM系统设计(1)系统设计原则①实时性原则
消息实时到达接收方 , 如果用户在线 , 则消息实时到达 , 如果用户不在线 , 则消息在用户登录后到达 。由于网络波动 , 以及移动端操作系统对应用前后台切换的管理 , 如何实现用户连接管理、消息实时推送 , 推送失败的处理方式 , 客户端重连机制 , 消息如何补齐等 , 都需要IM系统考虑 。由于TCP开发略微复杂 , 早期的基于HTTP短轮询、长轮询的低效的技术方案 , 也无法达到实时性的要求 。
②可靠性原则
是指我们经常听到的“消息送达” , 通常用消息的不丢失和不重复两个技术指标来表示 。可靠性是要确保消息被发送后 , 能够被接收者收到 。由于网络环境的复杂性 , 以及用户在线的不确定性 , 消息的可靠性(不丢失、不重复)是IM系统的核心指标 , 也是IM系统实现中的难点之一 。总体来说 , IM系统的消息“可靠性” , 通常就是指聊天消息投递的可靠性(准确的说 , 这个“消息”是广义的 , 因为还存用户看不见的各种指令和通知 , 包括但不限于进群退群通知、好友添加通知等 , 为了方便描述 , 统称“消息”) 。


推荐阅读