环信即时通信学习笔记

今天闲暇时间看了一下环信去年在CSDN的讲座视频,收获不少,在此做一下纪录。

前言:即时通讯(IM)功能是APP的重要功能之一,而开发好移动IM却绝非易事。通常来说,IM技术选型至少要解决以下问题:1. 协议选型 2. IM服务器选型 3. 对协议和服务器做相应修改,通常来说直接拿个标准协议和开源服务器是一定不能用到生产环境的 4. 保证消息到达率,绝不丢消息。 以上4点搞定后基本就有了一个可用的IM平台上。想更上一层楼,可以对电量和流量等做进一步优化,或者研究怎样支持百万级以上的用户。本次讲座将为APP开发者深入讲解移动IM开发的主要坑点,难点和解决方法。纯干货。

###协议选型

协议 简介 优点 缺点 典型案例
XMPP 基于xml的消息协议 广泛使用可扩展 流量较大 Jabber Gtalk Facebook SinaWeibo
MQTT IBM开发的一个即时通讯协议 多平台 简单的消息协议,要自己实现好友群组 推送
SIP 基于SIP,增加了message和presence扩展 已有SIP voip服务基础上支持短信 SIP信令控制的扩展,比较复杂 voip
私有协议 ActivitySync 对同步支持好,流量小 工作量大,扩展性差 微信

###IM服务器选型

服务器 语言 优点 缺点 典型案例
Openfire Java 成熟稳定 Java简单,模块化,使用Apache MINANIO,支持插件较多 对内存要求高,单机支持用户少(10万左右),集群支持相对薄弱 前端可用ConnectionManager的集群支持更多用户
Ejabberd Erlang 成熟稳定,强大集群支持,Hot deploy,Erlang支持多进程高并发 语言小众,开发成本高 Whatisapp

###XMPP协议的问题及改进

#####登陆握手部分的改进
XMPPQuickStart (XEP0305)

#####心跳改进
Xmpp Ping/Pong (XEP0199)40+字节 -> 单向 whitespace ping 4字节

#####文件传输
Xmpp协议的文件传输是点对点,需要改成用http上传的server,语音视频压缩后上传

#####Presence
对移动互联网场景,不转发是否在线 -- 永远在线

#####Muc聊天室
Muc是群聊天协议,要改进成移动社交app中的群组,发送消息时发送给群里的所有用户,而不是只发“在线”用户,disable presence

#####发送消息回执
NioConnection.java 里维护一个发送消息的队列,收到client端的回执,把消息从队列移除,在close()函数里,把未收到确认的消息存到offline msg里

#####离线通知插件
实现一个offline notification plugin
msgListener = new NotificationListener();
OfflineMessageStrategy.addListener(msgListener);

#####性能,状态数据和无线状态数据分离
不要使用内置数据库
Vcard 可以用 memorycache 提高访问速度
好友列表加载到内存 redis,提高效率(可以考虑用一台单独的server)

###移动网络环境下的优化

#####长链接的维护
Android 平台,维护client到server的长链接,添加网络监听,service自动重启
iOS平台直接用APNS即可

#####心跳包 GGSN
维护移动网 GGSN 路由

#####消息回执处理(ack)
移动网络有可能丢包,发送,接收需要加入回执机制

#####语音图片的收发优化

大文件分拆为多个数据包,每个包 10K 字节,如果发生失败,只需要重发一个包,而不是每次重发整个文件

#####流量电量优化(android)

######流量测量

1
2
3
uid = Process.myUid();
initRecvBytes = TrafficStats.getUidRxBytes(uid);
initSentBytes = TrafficStats.getUidTxBytes(uid);

######流量优化

  • 心跳
    减小心跳包尺寸
    减小发送频率
    智能心跳(频率不固定,空闲时才发)

  • 协议
    roster versioning (增量)
    xmpp quickstart
    推送更新

  • Transport
    Compress 将xml压缩成binary,http压缩

######耗电量测量

既要测量应用在前台的耗电,也要测量后台待机状态下的耗电量

######耗电量优化

  • 不要影响手机休眠
    通过alram manager 触发心跳包
  • 尽量减少网络请求
    本地db,内存cache数据,只同步增量,最好一次发送多个请求
  • 少用GPS定位
    发送位置时才定位,网络定位优先
  • 真对不同移动网络特性的优化
    移动网络下下载速度大于上传速度:2G一次发送数据包不要太大,3G,4G一次发送多更省电
    file upload buffer size:2G数据包 1024字节 3G,10k file download buffer size:2G 2048 3G 30k
  • 其他常规移动app开发优化
    对访问最多的数据,直接访问而不用get/set 能减少一次函数的调用开销,常用数据结构的重用 对象缓存等。

###client端各种问题及解决

#####数据同步
好友申请,群组邀请等的请求,数据同步需要支持离线,和断网两种情况,切换用户登录,不同设备之间同步

#####UI例子:位图显示效率和加载太多位图导致OutOfMemory

解决:

Image cache (Android LruCache)

Build in ThumbnailUtil vs Decode image file to thumbnail image

Call Bitmap.recycle()

###支持百万级并发(服务器)

  • Operation system
  • TCP/IP
  • Scale Out
  • Session Replication
  • Stateless Everything (or as much as possible)
  • Async Everything (or as much as possible)
  • Big Data
  • Multi Data Center

注:因为这全是设计服务器相关的点,本人目前还没有涉及太多,所以笔记没有做详细整理,见谅。