WebIM一般如何实现消息推送?
通常的有三种实现方式:
WebSocket;
FlashSocket;
HTTP轮询;
其中1和2是基于TCP长链接实现的,水友问的问题,主要是第三类,用HTTP短连接轮询的方式实现消息的收发,能否能保证消息的绝对实时性。
大家为什么会觉得HTTP长轮询有延时?
这要从大家理解的“轮询”说起。
什么是轮询?
举个栗子,在火车上想上洗手间,挤到洗手间旁,却发现洗手间有人,于是你只能回座位继续等。过了N分钟,又朝洗手间的方向挤过去,却发现洗手间还是有人,又只能回坐等。这么一而再,再而三的每隔N分钟去洗手间查看洗手间是否有蹲位,这就是轮询。
WEBIM采用上述轮询的方式收发消息会存在什么问题?
可能导致消息延时,某一时刻刚拉取完消息,突然又产生了一条新消息,这条消息就必须等到N分钟之后,下次轮询时,才有机会获取到。延时的最大值是N。
减小轮询时间间隔,是否能解决消息延时的问题?
不能,只能缩小延时,不能保证绝对实时。
同时还会产生更大的问题,大部分的轮询调用,都没有消息返回,造成服务端极大的资源浪费。
不少人基于上述直觉,认为WEBIM使用HTTP长轮询收发消息会有延时。但其实,HTTP长轮询压根不是这回事。
HTTP长轮询实际是怎么玩的?
专用消息连接。
什么是专用消息链接?
浏览器与web-server之间建立的,一条专门用来接受通知消息的HTTP链接。
专用消息连接的玩法细节如下:
没有消息到达的时候,专用消息连接将被夯住一段时间(例如:90秒);
夯住90秒,专用消息连接被断开之后,立马再发起一个专用消息连接;
在1和2的配合下,每次收到通知消息时,这个连接就能及时将消息带回浏览器页面;
在3的情况下,专用消息连接返回浏览器后,又立刻发起新的专用消息连接,如此一来,浏览器与web-server之间将永远有一条能够接受服务器通知的专用消息连接,以此,来保证WEBIM消息收发的绝对实时性。
总结
HTTP长轮询可以保证消息的绝对实时性;
这种实时性不是通过增加轮询频率来保证的;
而是通过专用消息连接,通过夯住HTTP请求来实现的,这个HTTP消息连接对于web-server的请求压力大约是90秒1次,能够大大节省了服务器资源。
知其然,知其所以然。
思路比结论更重要。