网站即时消息(WebIM)通常有三种方式实现推送
(1) WebSocket
(2) FlashSocket
(3) http轮询
其中(1)和(2)是用Tcp长连接实现的,其消息的实时性可以通过tcp保证。
方案(3)才算是webim实现消息推送的“正统”方案,用http短连接轮询的方式实现“伪长连接”。
什么是轮询
Webim每隔N分钟循环调用获取消息的接口,查看是否有消息,有消息则带回消息,没有则空返回。
轮询的时间(N分钟)就是消息延时的时间,缩小轮询时间可以缩短延时时间,增加消息的及时性,但是同时会产生新的问题,绝大部分的轮询调用接口,都是没有时间返回的,造成服务端极大的资源浪费。
轮询、长轮询、长连接之间的区别
轮询:客户端向服务器发送一个http连接,连接上服务器后,查询是否有消息需要推送,然后带回客户端,若没有,也返回,连接断开,再重新建立一个http连接。
说明:消息实时性不高,服务器压力大。
长轮询:客户端向服务器发送一个http连接,连接上服务器,查询是否有消息需要推送,若有则立刻带回客户端,若没有,则http连接一直保持连接,直到有消息需要推送或者连接超时,则返回,断开连接,然后立刻重新建立一条http连接。
说明:消息实时性比较高,延迟小。
长连接:客户端向服务器发送TCP连接,连接上服务器后,客户端与服务器会一直保持连接。当服务器有更新消息时会立刻发送到客户端,而连接不断开。(如果服务器长时间没有返回消息,会造成连接超时,客户端也会向服务器从新发送新的Ajax请求)。
说明:消息延迟小。
长短轮询和长短连接的区别
第一个区别是决定的方式:一个TCP连接是否为长连接,是通过设置HTTP的Connection Header来决定的,而且是需要两边都设置才有效。而一种轮询方式是否为长轮询,是根据服务端的处理方式来决定的,与客户端没有关系。
第二个区别就是实现的方式:连接的长短是通过协议来规定和实现的。而轮询的长短,是服务器通过编程的方式手动挂起请求来实现的。
长轮询实现消息推送
消息连接
Webim和webserver之间建立一条http连接,专门用作消息通道,这条连接叫http消息连接【见下图】
消息连接的4大特性:
1)没有消息到达的时候,这个http消息连接将被夯住,不返回,由于http是短连接,这个http消息连接最多被夯住90秒,就会被断开(这是浏览器或者webserver的行为)
2)在1)的情况下,如果http消息连接被断开,立马再发起一个http消息连接【见下图中的步骤1、2】
3)在1)和2)的配合下,浏览器与webserver之间将永远有一条消息连接在(极限情况下会出现4)),每次收到消息时,这个消息连接就能及时将消息带回浏览器页面,并且在返回后,会立马再发起一个http消息连接【见下图中的步骤1、2、3】
4)如果消息到达时,上一个http消息连接正在返回,没有http消息连接可用(理论上http消息连接的返回是瞬时的,没有连接可用出现的概率极小),则将消息暂存入消息池中,下一个消息连接到达后(上一个消息连接返回后,根据2)和3)会立马返回新的消息连接,无等待时间),将消息带回,并又立刻返回生成新的消息连接【见下图中的步骤1、2、3、4、5、6、7】
上述1-4就能够保证一直有一条http消息连接在,以保证webim消息推送的绝对实时性。
长轮询总结
Webim通过http长轮询可以保证消息的绝对实时性。这种实时性的保证不是通过增加轮询频率来保证的,而是通过夯住http消息连接来保证的,在大部分时间没有实时消息的情况下,这个http消息连接对于webserver的请求压力是90秒1次,能够大大节省了web服务器资源。