AJAX Polling
客户端定时请求服务器来询问是否有新的消息产生,这种情况下客户端每次请求都要建立一次http连接,服务器都要产生一个响应信息。
native
app里定时发http请求。 AJAX Long-Polling
跟上面的polling模式相比:
基于流的模式(http streaming)
在这种情况下,客户端与服务器端保持一个持久的连接,服务器端有新消息产生时通过这个持久连接不断地返回给客户端。这种模式与上面的long polling差不多,差别就是只需要创建一次连接就可以了。另外,要注意http header中需要设置Connection: keep-alive和Transfer-Encoding: chunked这两个属性。跟上面longpolling模式相比:
long
polling一,要保持大量连接和处理后台的消息更新。 HTML5 Server Sent Events (SSE) / EventSource:
除非Server-Sent Events不必在每一次响应发出后都关闭连接。
支持Chrome9+、Firefox6+、Opera11+、Safari5+
如果你觉得这些还不够,想要了解更多,可以参考下面的文件和手册
HTML5 Websockets
WebSocket是HTML5开始提供的一种浏览器与服务器间进行全双工通讯的网络技术,浏览器和服务器只需要要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相送。
目前WebSocket协议仍在开发中,目前Chrome和Safri浏览器默认支持WebSocket,而Firefox和Opera出于安全考虑,默认关闭了WebSocket,IE则不支持(包括9),目前WebSocket协议最新的为“76号草案”。有兴趣可以看以下资料 http://dev.w3.org/html5/websockets/
如果你觉得这些还不够,想要了解更多,可以参考下面的文件和手册
Flash Socket
在页面中内嵌入一个使用了Socket类的 Flash 程序JavaScript通过调用此Flash程序提供的Socket接口与服务器端的Socket接口进行通信,JavaScript在收到服务器端传送的信息后控制页面的显示。
WebRTC
WebRTC是一种点对点类型的传输方式,它支持多种传输协议,如:UDP、TCP甚至是抽象层的协议。设计它时同时考虑到了允许使用可靠和不可靠的两种方式传输数据。这种技术一般应用在传输数据量较大的内容,比如音、视频等流媒体的传输。
参考资料: https://developer.mozilla.org/zh-CN/docs/Web/API/WebRTC_API
Comet
Comet是一种用于web的推送技术,能使服务器实时地将更新的信息传送到客户端,而无须客户端发出请求,目前有两种实现方式,长轮询和iframe流。
如果你想了解更多,可以参考维基百科或者IBM
参考链接: http://stackoverflow.com/questions/11077857/what-are-long-polling-websockets-server-sent-events-sse-and-comet
在我们实际的应用中,各种方案应该怎么选择?
polling轮询机制很简单,使用方便,都是http短连接,在应用架构上跟普通接口api一致,非常适合小型应用和刚起步的应用,可以节省很多开发成本。
当用户量上升到一定程度后(比如日活跃百万级),产品做得越来越受欢迎了,我们对消息到达的及时性也就有更高的要求了,而且这种轮询机制对服务器压力也是一种考验,这时候我们就可以考虑long polling或http streaming的方式了,这两种方式其实在服务端实现上差不多,主要是保持大量长连接和异步(或事件触发)获取消息。
在保持连接方面,在java的nio出现后,为我们提供了便利,主流的应用服务器像tomcat和jetty都有支持,但是,工作在jvm上的服务器保持大量socket连接时gc是个很严重的问题。可以借助nginx的push模块来实现保持连接以及消息实时推送。
这两个模块工作在nginx上,可以维持大量的http连接,实现了pub/sub协议来支持消息发送,基本流程是下图这的,发送者(publisher)把消息推送到nginx服务器上,然后push模块负责把消息发送给订阅者(client):借助nginx的这个push模块,我们可以省去大量的工作,应用程序只需要关注业务逻辑(也就是publisher做的事),简化了应用架构,同时nginx的高性能也有不错的表现。
当我们的产品发展到千万级的日活跃时,我们可能就要考虑更好的方案了,比如上面的提到的WebSocket,但是为浏览器兼容的问题,这个方案并不是主流的解决方案。一般这种情况下,我们就要考虑基于tcp的socket长连接模式了,通过某种消息推送协议(xmpp/mqtt/自定议协议等)来实现客户端和服务器端的实时交互。
其他相关资料: http://socket.io/