分享 移动 IM 学习笔记

easyhappy · 2014年11月06日 · 最后由 esseak 回复于 2014年12月09日 · 27665 次阅读
本帖已被管理员设置为精华贴

最近在看移动 IM 相关的资料,然后发现网上有很多的资料,所以在学习过程中,整理了一些笔记,供那些 想了解 移动 IM 的童鞋一些参考。

移动 IM 技术选型要点

1、协议选型 2、IM 服务器选型 3、协议和 IM 服务器改造 4、移动 IM 常见问题以及一些解决方案 5、一些第三方服务

一、常用的 IM 协议

二、IM 服务器的选择

经过这几天在网上的调研,发现目前比较流行的几个 IM 服务器 也就是 Openfire、Tigase, Ejabberd:

备注: 详解 Zoosk 千万用户实时通信背后的开源技术

三、XMPP 协议的问题及改进

1、登录握手部分改进
Xmpp QuickStart

2、心跳改进
原先 Xmpp 使用的 Ping/Pong 40+ 字节,改进为单向 white space ping, 4 字节。
备注:心跳单向四个字节,在 Xmpp 协议下,估计应该是极限了吧。在私有协议协议下,一来一往两个字节足够。

3、文件传输

  • Xmpp 的文件传输采用的点对点的传输; 改进为 http 上传到 server
  • 语音、视频压缩上传
  • 图片默认下载缩略图

4、Presense

移动互联网环境下,不管用户是否在线,都会假设 用户永远在线。
这是因为移动网络环境导致,比如从 wifi 切换到 3G、处于地铁、WIFI 边缘地带等,如果还采用 PC 端 类似 QQ 那种方式,很可能会造成重连风暴。

5、Muc 聊天室

Muc 是聊天室协议,在业务层面进行改进,发送消息时 发送给所有用户,不管他在不在线

四、基于 Openfire 服务器的改进

1、发送消息回执

在 server 端维护一个消息队列,当收到 client 发送会的消息回执时,将这个消息删掉

2、性能改进

不要使用内置的数据库,对于 Vcard 或者好友列表信息 可以考虑放到 Redis

3、如果是消息量很大的话,消息存储可以使用 Kafka(和数据库集群之间存定时拉取关系),分布式锁基于 Zookeeper,前端 LVS 做负载均衡。

五、移动 IM 的那些坑点

1、长连接

android 平台 维护 client 到 server 的长连接

IM 或推送,建立长连接是必须的,可以节省 TCP 来回创建的开销,但断线之后,是否需要即刻重连,尤其是处于地铁、WIFI 边缘地带,可能会造成重连风暴,需要添加稍加延迟连接机制。

2、心跳包 GGSN

维护移动网 GGSN

3、消息回执处理 Ack

移动网络很容易丢包,发送、接受应加入回执处理

4、语音、图片的收发优化

大数据拆分成多个包,一个包大概 10 字节

六、第三方的 IM 服务

1、环信(个人感觉选他不错), 大概是从 2013 年 4 月创立,到目前为止号称 有 6000 万注册用户,有 1000+ app 使用

2、leancloud 2013 年 9 月发布以来,已经吸引了近万移动应用和开发者加入。

七、结论

如果说自己搭建一套 IM 框架的:

  • 基本能用需要 3 个月
  • 做的比较好需要 9 月到 1 年时间
  • 做的像微信一样,那么需要 2 年时间

如果说基于现有的 IM 服务器搭建的话,个人觉得 从 IMserver 性能以及后期维护和招人成本上来看,应该是 Tigase > Openfire > Ejabberd

八、写在最后

如果你也对 IM 感兴趣的话,可以看一看 环信的一个讲座, 对应的ppt
当然了,由于我本人接触 IM 这块也不太久,所以肯定会有一些遗漏,欢迎大家提意见呀...

我也折腾过一阵。最大的感触是 ejabberd 没有 erlang 大牛就别去折腾了。openfire 倒是可以,但是大家都说集群支持差,没实践过。如果只是作为一个模块,第三方服务方便。

明显 Ejabberd 最容易了。我不会 Erlang 都一下午就上手了,那个 Tigase 也还行。OpenFire 一个星期都搞不定啊 ...

@bhuztez 但是 ejabberd 的二次开发、团队筹建 怎么破?

确定这不是一篇软文?鄙视环信

下面内容取自环信的 FAQ,觉得他们还是做了很多工作的,如果是小团队,真没必要自己折腾。 是不是软文不是很重要了,其实现在也就这两家靠谱吧。

http://www.easemob.com/faq/#section-4

** 开源的 IM 框架也有不少,为什么我不可以自己搭建一个 IM 服务器,自行开发呢? ** a) 自行研发移动 IM,技术门槛高,开发周期长。根据我们的经验,至少需要资深的 Android 工程师,iOS 工程师,后台工程师各一名,需要至少 2 到 6 个月时间。主要的技术难点包括:

  • 协议和 IM 服务器的选择:当前常用作 IM 的协议包括 XMPP 和 MQTT,也有用 SIP 的,还有自行开发的私有协议。- - 可以使用的开源的 IM 服务器包括 OpenFire, Tigase, Prosody, Mosquitto, ejabberd 等。你知道它们各自的优缺点吗,你知道哪个协议,那个 IM 服务器实现最适合你的需求吗,你知道你一旦选定了一个方案,你分别需要对协议和 IM 服务器做哪些改动和改进吗?
  • 不稳定网络环境下(3G,2G,Wifi,无网络,及各种网络环境下的切换)移动终端即时通讯长连接可靠性的维护
  • 移动终端耗电量优化
  • 移动终端流量优化
  • 发送各类富媒体消息的特定处理,如语音文件格式选择,语音压缩算法,语音降噪算法,图片压缩处理,地理位置,名片,文档等
  • 消息回执处理 (ack),防止消息丢失。
  • 离线消息处理。离线时的实时消息通知(比如通过第三方推送平台)
  • 实时状态同步
  • 支持千万级同时在线用户的高可靠,高并发的服务器集群架构的搭建和运维
  • 安全

b) 移动 IM 是一个需要长期跟进和维护的技术,并不是产品上线后研发团队就可以解散了。作为运营者,你做好长期的技术投入的思想准备了吗?比如新的 IM 功能层出不穷,如匿名社交,阅后即焚,你的产品要不要与时俱进?移动 IM 相关的各种安全隐患和漏洞,你要不要及时修复?所以你需要问自己一个问题,移动 IM 技术是你的核心竞争力吗,还是只是支撑你的业务实现的一个工具?

c) 移动 IM 服务对服务器硬件,网络,运维环境,都有非常高的要求。需要长期持续的服务器端运维投入。

d) 绝大多数团队都不具备百万级,千万级并发的 IM 技术。一旦用户量爆发性增长,APP 的基本可用性会有极大的隐患。

之前,搞过 openfire,感觉还好。

前一段时间,我在阿里云搞了台 ECS 服务器,装了 OpenFire,写了一个 iPhone 版类似微信的聊天 Demo玩玩,可以发图片、文字和语音,如下截图。确实,如果要做成产品级,还需要很多的开发工作,抛砖引玉吧。 image

socket.io 怎么样

之前用 Nodejs 写过一个简单的即使聊天,web 端+ios+android。

好的地方感觉就是 web 端的 js 不用自己写了,各种兼容性都考虑了,移动端的库也多。也还稳定。

leancloud 的及时通讯感觉也和 socket.io 差不多,web 端 websocket + polling,移动端 websocket

:plus1: @jimneylee 看起来挺棒,mark

@wikimo 算一个学习练手的 demo 吧。😄

当时我们做了 1 年,2 个后端

@esseak 你们是从 0 开始,还是基于 openfire 或者 ejabberd 改的?

#13 楼 @meeasyhappy 我的是后台搭建个 OpenFire,前端 iOS 基于 (XMPPFrameWork)[https://github.com/robbiehanson/XMPPFramework],国外这个框架很赞。

小贝,牛逼!

XMPP 协议的最主要的一点就是开放,不管是协议、客户端,还是 Server 端,都有成熟的实现方案。为了实际感受 XMPP 协议的聊天过程,我使用 asmack library + OpenFire 服务器搭建了一套完整的测试环境。OpenFire 采用 Java 开发,是一个基于 XMPP 协议 的开源的实时协作服务器,它的安装和使用都非常简单,自带有一个内置的存储数据库(当然,你也可以使用独立数据库如 Mysql 等),并利用 Web 进行管理。其他类似的开源系统还有很多,eJabber、Tigase 也经常被用到。但是根据我们之前的经验,这些开源系统能支持的并发连接数都不高,要是有超过 10 万的用户同时连上来,对它们来说就快达到单机的瓶颈了,这时候一般都需要水平拆分,但是拆分之后服务器之间的 session 同步负担会大幅加重,对于性能又带来不小的抵消。所以这些系统大都被拿来做研究和测试用,很少见到大规模在生产环境中使用的。 以上摘录于 该博文

18 楼 已删除

移动 IM 用 XMPP 很耗流量的

震惊于 RubyChina 的查看图片功能非常爽。

#13 楼 @meeasyhappy 抱歉回复晚了,不登录浏览是个坏习惯。当时我们是改的 openfire,毕竟 java 人员比较好找。但是当时 openfire 性能(也许是我们不了解)和分布式方案都不是很好,然后我们又重写了服务端,自己用 socket 实现了 xmpp 协议(部分),然后就呵呵了。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号