特点
- 实时性
- 支持群聊与广播
- 多媒体:text, image, vioce or video
难点
- 顺序
- 丢包
- 重复
设计
- client
- server
- 会话/群聊
- 协议
- 登陆,身份验证
- 连接
- 发起会话
- 退出会话(退群)
- 消息接收设置
- 心跳
-
长连接
- 终端
- 接入层: ConnectSvr
- 逻辑层: SenderSvr, PushSvr, ReceiveSvr
- 存储层: MsgStore
设计权衡
聊天记录要不要保存?保存多久?客户端保存还是服务器保存?
要不要使用系统推送?应用长连接推送在应用没有启动或者退出到后台的时候无法接收消息?
如苹果的ApnsPush,微软的WPPush,黑莓的BBPush等)。像苹果的ios系统,在app退出到后台10分钟后就会释放掉该app所持有的所有资源(如cpu,网络,内存等),导致之前建立的长连接通道也会一并断掉,此时通过业务长连接进行通知是不可达的,所以还需要依赖与苹果自身的apns通道来达到实时通知。
支持纯文本还是多媒体?至少要支持表情?
支持群聊吗?
要不要有群的概念?还是多人聊天的概念?
要不要有在线状态的概念?
要不要有好友的概念,聊天需要不要先通过验证?
安全。聊天信息要不要加密?聊天记录的保存。
服务器需要存储的信息
- 用户、注册id和链接:一个用户可以有多个注册id,因为可以多台设备登陆。但是像微信是要求如同一个账号在同一时间只能有一台设备登陆在线。
- 如果用户有朋友关系,那么需要保存朋友链。
- 如果用户有消息结构设置,那么也需要配置。
- 如果有会话/群聊,那么也需要有一个标示,以便用户加入。
参考方案
现在国内的移动IM霸主显然是微信。那么微信是怎么设计和实现的呢?
微信团队诞生于广研的QQ邮箱团队,所以整个微信后台架构都带着浓重的邮箱气息,特别是最核心的消息收发功能,就是基于邮箱的store-forward的机制演变而来的。大概思路如下:
- 每人对应一个收件箱,A发消息给B,就往B的收件箱里推送一份消息,群发就给每个成员的收件箱推一份消息。
- 用户收件箱有消息时,通过在线中心向用户发信令通知,客户端再从服务器主动拉消息;被客户端取走的消息直接删除。
- 收件箱每人20MB,长时间不拉取就删了。
这个设计足够简单粗暴,但也限制了一些产品特性,比如历史记录(新加一个群,显示几条前面的消息挺好的,省的再复制说一遍),比如朋友圈的评论(向所有共同好友发送消息)中没法看新加共同朋友之前的评论。
微信定位为即时通讯软件,对消息的收发有三个基本的要求:
- 消息尽可能的实时送达
- 顺序到达
- 不丢消息
在邮箱的存储转发机制上做了改良后,微信的消息收发实现了以上3个基本要求。