通常情况下,无论是浏览器还是移动端,与服务器之间的交互都是主动的,即客户端向服务器端发发出请求后,服务器端将数据返回给客户端,他们之间的对应模式为:客户端请求--服务端响应。
但若想要服务器端主动将信息推送给客户端,例如实时金融证卷信息、订阅新闻,天气提醒、监控系统等,都需要服务器主动推送消息给客户端。
目前解决该问题的技术:
一、反向Ajax技术
反向Ajax技术即通过实用技术模拟服务器端和客户端之间的响应通信来绕过Ajax只能从客户端向服务器端发出请求的限制。其说白了还是传统的请求模式,这是在后台做的,前台看不出来。
Http轮询:
即定时的通过Ajax查询服务器端,客户端定时向服务器端发送ajax请求,服务器端接收到请求后马上响应信息并关闭连接。要求两次请求间隔时间必须尽可能的小,但若时间间隔减小,客户端浏览器在相同时间内就会发出更多的请求,这些请求中大部分都不会返回有用的数据,这会白白地浪费掉带宽和处理资源。
JSONP轮询:
JSONP轮询和HTTP轮询类似,不同之处在于使用JSONP可以发送跨域请求(请求不属于您所在的域),JSONP请求通常可以通过它的调用参数和返回内容识别出来,其是可执行的JavaScript代码。要想在 JavaScript 中实现轮询,可以使用setInterval来定期地发出 Ajax 请求。
这种技术实现起来非常简单,但它不具有伸缩性,需要不断地向服务器端发送消息,会对服务器造成极大的性能浪费,加重网络负载,拖累服务器。
Piggyback polling(捎带轮询):
捎带轮询是一种比轮询更聪明的做法,它会删除所有非必需的请求(没有返回数据的那些),且不存在时间间隔,客户端在需要的时候向服务器端发送请求。不同之处在于响应的部分,响应被分成两个部分:对请求数据的响应和对服务器时间的响应。捎带轮询通常针对服务器端的所有 Ajax 请求可能会返回一个混合的响应。
这种方法因为客户端控制了何时发送请求,所以没有不返回数据的请求,对资源的消耗较少,可用在所有浏览器上。但这仍然算是客户端主动去请求服务器端,当服务器累积了事件想要传送端户端时,在客户端没有发送请求时也不能主动发送给客户端。
二、Comet
Comet基于HTTP长连接的“服务器推”技术,是一个Web应用模型,能够将服务器实时地将更新信息传送到客户端,目前有两种实现方式,长轮询和iframe流。
实现原理是客户端发送请求到服务端,服务器端会阻塞请求直到有数据传递或超时才返回,之后客户端 JavaScript 响应处理函数会在处理完服务器返回的信息后,再次发出请求,重新建立连接。当客户端处理接收的数据、重新建立连接时,服务器端可能有新的数据到达;这些信息会被服务器端保存直到客户端重新建立连接,客户端会一次把当前服务器端所有的信息取回。即还是要客户端先贡献它的“第一次”,只要客户端先请求服务器端一次,以后两端就熟了,服务器端想主动约客户端就约。
Comet 的一大优点是,每个客户端始终都有一个向服务器端打开的通信链路。服务器端可以通过在事件到来时立即提交(完成)响应来把事件推给客户端,或者它甚至可以累积再连续发送。因为请求长时间保持打开的状态,故服务器端需要特别的功能来处理所有的这些长生存期请求。
HTTP长轮询:
长轮询(long polling)模式涉及了打开连接的技术,连接由服务器端保持着打开的状态,只要已有事件发生,响应就会被提交,然后关闭连接。而后一个新的长轮询连接就会被正在等待新事件的客户端重新打开。实现可以使用 script 标签或是单纯的XMLHttpRequest对象来实现 HTTP 长轮询。
iframe流:
iframe流方式是在页面中插入一个隐藏的iframe,利用其src属性在服务器和客户端之间创建一条长链接,服务器向iframe传输数据(通常是HTML,内有负责插入信息的javascript),来实时更新页面。从技术上来讲,两种常见的流技术包括 Forever Iframe(或者 hidden IFrame),或是被用来在 JavaScript 中创建 Ajax 请求的XMLHttpRequest对象的多部分 (multi-part) 特性。
iframe流方式的优点是浏览器兼容好,但没有方法来实现可靠的错误处理或跟踪连接的 状态,且有些在缓冲方面有问题。
三、WebSocket
WebSocket是一种在单个TCP连接上进行全双工通讯的协议,它允许服务器端主动向客户端推送数据,在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
而比较新的技术去做轮询的效果是Comet。这种技术虽然可以双向通信,但依然需要反复发出请求。而且在Comet中,普遍采用的长连接,也会消耗服务器资源。在这种情况下,HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。WebSocket 协议在2008年诞生,2011年成为国际标准。所有浏览器都已经支持了。它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。
其他特点包括:
(1)建立在 TCP 协议之上,服务器端的实现比较容易。
(2)与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
(3)数据格式比较轻量,性能开销小,通信高效。
(4)可以发送文本,也可以发送二进制数据。
(5)没有同源限制,客户端可以与任意服务器通信。
(6)协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。
如:ws://example.com:80/some/path
参考资料:
Ajax和Comet:https://www.ibm.com/developerworks/cn/web/wa-reverseajax1/index.html
https://www.ibm.com/developerworks/cn/web/wa-lo-comet/
WebSocket:http://www.ruanyifeng.com/blog/2017/05/websocket.html
https://www.cnblogs.com/study-everyday/p/6140498.html