大家好,今天和大家聊下即时通讯IM中的相关问题,分如下几个部分:
一:即时通讯的应用场景。
除了现在主流的即时通讯社交应用(例如:微信、企业微信、钉钉等)是IM典型的应用场景,还有近几年已经兴起来的视频直播中粉丝互动信息打赏场景,以及各个购物网站中包含的客服模块,随着网络上与人沟通的场景和需求不断增加,即时通讯这个功能会在越来越多的应用中嵌入。
二:IM移动端功能组成。
一个即时通讯APP,包含下面主要功能:
1)联系人列表;
图片来自于“即时通讯网”
像微信的通讯录是通过加好友得到的,而如果是企业微信、钉钉等办公类,通讯录一般是事先配置好的公司各部门人员,应用启动的时候,通过接口拉取下来并存储在本地的数据库表中,如下:
包含域账号、部门、姓名、性别、头像、电子邮箱、手机号等个人基本信息。
2)聊天页面;
图片来自于“即时通讯网”
聊天页面是整个IM中最核心的模块,所有的IM功能都是通过它来展现:
- 各种聊天功能按钮:语音留言、图片、文字、表情、文件、实时电话、实时视频;
- 各种聊天显示:各种消息都有不同的UI显示元素和处理逻辑;
- 流程的使用体验:大量不同类型的消息显示时,不能卡顿;
- 及时显示聊天信息:网络收到的消息,要马上在UI上显示处理;
- 历史消息的加载:上次聊过的内容也能显示出来;
以上是主要的功能。
3)消息发送通道;
移动端发送消息,基于Netty框架进行消息的write进行发送。但这里涉及Netty框架的了解,及和后端一连串的动作,如下图所示:
图片来自于“即时通讯网”
如上图所示,消息发送通道,就是用TCP或UDP,建立Socket连接,需要发送消息的时候,write一下就过去了,但我们还需要了解如下功能:
- 如何保证这条socket长连接时一直处于可用的状态;
- 当socket长连接不可用时,用户此时发送的消息该怎么办;
- 怎么保证发送的消息不丢;
- 怎么保证发送的消息不重复;
- 怎么保证发送的消息不乱序;
- 当对方不在线时,发送的消息去哪了;
- 发送的消息,能保证实时到达吗;
这其中涉及很多后端相关的操作,作为移动端开发的我们,要想深入玩转这块流程,并能处理各种移动端的疑难杂症bug,都需要对上面的问题有一定的了解。
4)消息接收通道;
和上面消息接收通道相对应,对方通过发送通道write消息,我得到并显示。
可靠的消息接收通道,包含以下:
- 如何保证socket长连接通道能随时处于良好的连接状态(随时接收对方write的消息);
- 当socket长连接断开时,对方发送消息该怎么实现;
- 当socket恢复连接时,怎么恢复之前的聊天现场;
- 当我收到对方的消息时,对方怎么知道我已经收到了;
- 当重复收到对方的消息时,该怎么处理;
- 当收到的消息时序有错乱,该怎么处理;
同样,解决移动端各种问题,需要对上面的问题有一定的了解。
5)消息存储;
消息存储分客户端APP的消息存储和服务端的存储,如果客户端的消息没有存储,那退出应用下次再进来,就没有之前的聊天记录;如果服务端没有存储,当用户不在线或多端(移动端和PC端)消息同步时,客户端都会出现消息丢失的情况,这个聊天体验就很不好。
服务端的角度:
- 对方不在线时:聊天消息应该存储(离线消息存储)
- 对方在线时:聊天消息也要存储(消息缓存)
- 对方在线或不在线:聊天消息都要存到服务端(实现多设备的消息漫游和同步)
客户端的角度:
- 接收到的消息,都要进行本地数据库缓存。
下图是一个IM系统的典型存储架构设计
图片来自于“即时通讯网”
6)消息未读数;
图片来自于“即时通讯网”
消息未读数可以很好的提醒用户来了多少条新消息,有会话未读数和总未读数。包含以下功能:
- 未读数是客户端实现还是服务端实现--我做的是客户端实现;
- 会话未读数和总未读怎么保持一致--各个会话未读数相加;
- 多终端情况下(手机和PC端),怎么保证未读数的一致性(我在这台设备上读没读,另一台设备怎么知道的);
二:长连接(TCP)和短连接(HTTP)的区别。
短连接其实就是http(https)接口请求,属于pull型,我们应用中绝大多数的数据来源(例如首页模块的banner、新闻等)都是通过主动发起接口请求获得,服务端返回数据,该连接状态就结束了,及时释放资源。
长连接字面意思就可理解成一直在连接中,发起方可随时发送数据,接收方可随时接收数据,通过socket来实现,基于TCP来实现。
三:为什么需要心跳检测
心跳和长连接相关,顾明思议就是证明是否还活着的依据。大多数基于长连接的应用需要心跳来“保活”。由于在长连接的场景下,客户端和服务端并不一致处于通信状态,如果双方长时间没有沟通则双方都不清楚对方目前的状态,所以需要发送一段很小的报文告诉对方“我还活着”。
同时还有另外几个目的:
- 服务端检测到某个客户端迟迟没有心跳过来可以主动关闭通道,让它下线;
- 客户端检测到某个服务端迟迟没有响应心跳也能重连获取一个新的连接;
引用参考连接:http://www.52im.net/thread-3065-1-1.html