如何实现实时交互
现在,很多网站为了实现推送技术,所用的技术都是轮询。轮询是指在特定的时间间隔(如每一秒),由浏览器对服务器发起HTTP请求,然后由服务器返回数据给浏览器
。由于HTTP协议是惰性的,只有客户端发起请求,服务器才会返回数据。轮询技术实现的前提条件同样是基于这种机制。而WebSocket属于服务端推送技术,本质是一种应用层协议,可以实现持久连接的全双工双向通信。在介绍WebSocket之前,先了解下传统web上的实时数据交互方式
- 定期轮询的方式:
客户端按照某个时间间隔不断地向服务端发送请求,请求服务端的最新数据然后更新客户端显示。这种方式实际上浪费了大量流量并且对服务端造成了很大压力。
- comet技术
comet并不是一种新的通信技术,它是在客户端请求服务端这个模式上的一种hack技术,通常来讲,它主要分为以下两种做法
- 基于长轮询的服务端推送技术
具体来讲,就是客户端首先给服务端发送一个请求,服务端收到该请求之后如果数据没有更新则并不立即返回,服务端阻塞请求的返回,直到数据发生了更新或者发生了连接超时,服务端返回数据之后客户端再次发送同样的请求,如下所示:
- 基于流式数据传输的长连接
通常的做法是在页面中嵌入一个隐藏的iframe,然后让这个iframe的src属性指向我们请求的一个服务端地址,并且为了数据更新,我们将页面上数据更新操作封装为一个js函数,将函数名当做参数传递到这个地址当中,
服务端收到请求后解析地址取出参数(客户端js函数调用名),每当有数据更新的时候,返回对客户端函数的调用,并且将要跟新的数据以js函数的参数填入到返回内容当中,例如返回“”这样一个字符串,意味着以data为参数调用客户端update函数进行客户端view更新。基本模型如下所示
- HTTP流
HTTP流不同于轮询技术,HTTP流只建立一次TCP连接,在3次握手之后进行HTTP通信,此时客户端向服务器发起一个HTTP请求,而服务器保持连接打开,周期性的向客户端传输数据。双方在没有明确提出断开连接时,服务器就会持续向客户端传输数据。也就是说,假如服务器数据没有更新,服务器不会返回响应,而是保持连接;如果数据更新了,会立即将数据传输给客户端。此时会发起下一个HTTP请求,过程周而复始。
在JS中,可以通过侦听readystatechange事件及检测readyState的值是否为3来实现HTTP流。随着不断从服务器接收数据,readyState的值会周期性的变为3。当readyState值变为3时,responseText属性就会保存接受到的所有数据。此时,就需要比较此前接收到的数据,决定从什么位置开始取得最新的数据。
Websocket
websocket与http
WebSocket是HTML5出的东西(协议),也就是说HTTP协议没有变化,或者说没关系,但HTTP是不支持持久连接的(长连接,循环连接的不算)
首先HTTP有 1.1 和 1.0 之说,也就是所谓的 keep-alive ,把多个HTTP请求合并为一个,但是 Websocket 其实是一个新协议,跟HTTP协议基本没有关系,只是为了兼容现有浏览器的握手规范而已,也就是说它是HTTP协议上的一种补充可以通过这样一张图理解
有交集,但是并不是全部。简单来说,层级不一样。
Websocket的通信原理和机制
websocket本身虽然也是一种新的应用层协议,但是它也不能够脱离http而单独存在。具体来讲,我们在客户端构建一个websocket实例,并且为它绑定一个需要连接到的服务器地址,当客户端连接服务端的时候,会向服务端发送一个类似下面的http报文。
可以看到,这是一个http get请求报文,注意该报文中有一个upgrade首部,它的作用是告诉服务端需要将通信协议切换到websocket,如果服务端支持websocket协议,那么它就会将自己的通信协议切换到websocket,同时发给客户端类似于以下的一个响应报文头
返回的状态码为101,表示同意客户端协议转换请求,并将它转换为websocket协议。以上过程都是利用http通信完成的,称之为websocket协议握手(websocket Protocol handshake),进过这握手之后,客户端和服务端就建立了websocket连接,以后的通信走的都是websocket协议了。所以总结为websocket握手需要借助于http协议,建立连接后通信过程使用websocket协议。同时需要了解的是,该websocket连接还是基于我们刚才发起http连接的那个TCP连接。一旦建立连接之后,我们就可以进行数据传输了,websocket提供两种数据传输:文本数据和二进制数据。
websocket的使用场景:
基于以上分析,我们可以看到,websocket能够提供低延迟,高性能的客户端与服务端的双向数据通信。它颠覆了之前web开发的请求处理响应模式,并且提供了一种真正意义上的客户端请求,服务器推送数据的模式,特别适合实时数据交互应用开发。
一般我们做聊天室这种需要保持通讯状态的功能,如果是用HTTP协议去做的话,需要客户端一直做长轮询去查询服务端是否由新消息,再显示在客户端上,这是因为HTTP本身是一个短连接,当我们客户端发起请求时,服务器端响应完请求将结果返回给客户端,这个连接就自动断开了,这个过程http服务端是被动的,而websocket不仅客户端可以做请求响应,服务器端也可以做请求响应,即它可以实现往客户端主动推送消息,这样做聊天室就非常方便了。
websocket它实现了浏览器与服务器全双工(full-duplex)通信。其本质是保持TCP连接,在浏览器和服务端通过Socket进行通信。而HTTP只支持单工通信,http自动断开,websocket会一直保持长连接,除非你主动请求断开
WebSocket 目前在各大主流浏览器的支持都比较好