浏览器如何和服务器保持实时通信呢?常用的有以下四种方案:

(1).ajax,每隔一定时间发送一次请求。

(2).长轮询,http链接建立后,如果服务器还没有数据要返回的话,这个http链接就halt住,一直halt到有数据了然后发送给浏览器,然后再次发起第二次HTTP链接...重复上述过程。

(3).长连接(SSE)

严格地说,HTTP 协议无法做到服务器主动推送信息。但是,有一种变通方法,就是服务器向客户端声明,接下来要发送的是流信息(streaming)。

也就是说,发送的不是一次性的数据包,而是一个数据流,会连续不断地发送过来。这时,客户端不会关闭连接,会一直等着服务器发过来的新的数据流,视频播放就是这样的例子。本质上,这种通信就是以流信息的方式,完成一次用时很长的下载。

SSE 就是利用这种机制,基于http协议,使用流信息向浏览器推送信息。不过,SSE是单向通道,只能服务器向浏览器发送,因为流信息本质上就是下载。如果浏览器向服务器发送信息,就变成了另一次 HTTP 请求。

(4).websocket

     Websocket协议和HTTP协议都位于网络中的应用层,都是应用层协议,而TCP则是位于传输层,属于传输层协议,并且WS和HTTP都是基于TCP实现的上层协议,与HTTP不同的是,WS可以使得客户端(广义客户端,包括浏览器)与服务器建立一个长链接全双工的通信信道,不仅使得客户端可以主动向服务器发送消息,也可以让服务器主动向客户端发送消息,由于是长链接通道所以每次消息的发送并不会反复创建、销毁链接。

      需要注意的是,websocket链接的建立第一步是借助于HTTP协议实现的,后面才是真正的WS链接。ws链接建立时,里边有几个http header如下要注意。

  • Connection: Upgrade   // 告诉服务器,这个链接要进行协议升级。实际上这个header平时用的更多时候,TA的值是赫赫有名的keep-alive
  • Upgrade: websocket    // 告诉服务器,具体想升级成websocket协议

  • Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits    // 协议扩展类型
  • Sec-WebSocket-Key: IhTmM/PyVb55uCkAU5Iw1Q==    // 传输给服务器的key,这个key的算是这样来的 客户端随机一坨字符,然后base64一下
  • Sec-WebSocket-Version: 13   // 客户端支持WebSocket的版本
  • Sec-Websocket-Accept和Sec-WebSocket-Key具体是怎么个联系呢?这两个玩意实际上是WS进行握手的关键数据。