Java for Web学习笔记(四四):WebSocket(1)演化历程

Ajax的问题

Ajax即Asynchronous JavaScript and XML,不局限于XML,现在更多用Json。Ajax通过JavaScript提供了server之间的异步通信,可以在不刷新不改变页面的情况下server进行通信。但Ajax有一个问题,client不知道什么时候server有新的数据需要获取。下面介绍几种主要的解决方案。

频繁轮询(Frequent Polling)

定期向server发送Ajax请求,通常一秒一次,无论client还是server,如有新信息都附加在http的请求和应答中。这种方式简单有效,但是缺点明显,浪费了大量资源。

长轮询(Long Polling)

Java for Web学习笔记(四四):WebSocket(1)演化历程_第1张图片

在Long Polling中,Server在有信息回复给客户端的时候进行响应。和frequent polling相比更有效率,但是:

  • 如果client有新的内容送给Server,要么另起一个HTTP请求,要么把这个长连接给中断后在起一个新的
  • TCP和HTTP是可设定连接超时的,server和client要定期关闭和重新建立连接,通常是60秒,但是也有几分钟的。
  • 在HTTP/1.1规范中,浏览器不允许同时保持对某个hostname有超过两条以上的连接。如果其中有一个用于长轮询,那就只剩一条连接用来获取该server的网页,图片等资源。

尽管如此,长轮询的方式在过去几年仍获得广泛的使用。

分块编码(Chunked Encoding)

在 Filter(2):处理异步请求中,我们介绍了Transfer-Encoding: chunked的chunked方式。利用分块发送的机制,解决长轮询中的timeout问题,并无需建立多次连接。每个chuch是一个新的事件将触发JavaScript XMLHttpRequest对象的onreadystatechange事件处理。如果client需要发送新的内容给server,则要另起一个http连接。和Long Polling一样,受限于同一host同时只有两条连接的限制。

Java for Web学习笔记(四四):WebSocket(1)演化历程_第2张图片

Applet或Adobe Flash

通过在页面上嵌入1px大小的透明的Java Applets或者Adobe Flash movies,在client和server之间建立一条非HTTP的TCP长连接。当server发送信息给浏览器时,Applet或者Flash将调用JavaScript函数,给出信息;当浏览器发送信息给Server,将调用浏览器plug-in通过JavaScript DOM喊出提供的Java或者Flash方法。这种方式规避了HTTP的限制,但是要求第三方插件(不适用于手机浏览器),会导致安全隐患、运行缓慢和内存消耗,因此这种方式也只是短暂的一段时期流行。

Java for Web学习笔记(四四):WebSocket(1)演化历程_第3张图片

WebSocket

HTTP/1.1 14.42:HTTP Upgrade

在HTTP/1.1协议 RFC 2616 的14.42定义了HTTP Upgrade:

The Upgrade general-header allows the client to specify what additional communication protocols it supports and would like to use if the server finds it appropriate to switch protocols.The server MUST use the Upgrade header field within a 101 (Switching Protocols) response to indicate which protocol(s) are being switched. [1]

通过HTTP请求的Connection: Upgrade以及Upgrade:xxx(支持转换的协议们),以及101响应中给出的转换协议,可以将HTTP协议转为其他协议。早期主要用在HTTP和HTTPS的转换,但是由于整个连接不完全是安全的,仍会受到攻击,这种方式已经很少用来,采用直接使用HTTPS URI scheme。我们可以利用将HTTP协议转换为TCP协议,从而实现双向信息交互。原则上可以转换为任何的TCP协议,但浏览器需要能够识别并提给JavaScript,由此WebSocket协议诞生。

如果server对某资源的请求必须要求HTTP Upgrade,可以回复426 Upgrade Required ,并带可携带Connection: Upgrade和Upgrade头。如果server不支持HTTP Upgrade给出来的协议,回复400 Bad Request,并可携带Upgrade头表明其支持的协议。

RFC 6455:The WebSocket Protocol

利用HTTP Upgrade发展了WebScoket协议,形成 RFC 6455。

Java for Web学习笔记(四四):WebSocket(1)演化历程_第4张图片

在HTTP所承载的同一条TCP连接上:

  1. client和server通过HTTP请求以及101响应进行握手协商
  2. 握手成功后,双方可以进行双向的数据传递。由于承载在原来HTTP所在的TCP,防火墙会放行。但是对于HTTP Proxy还是有可能出现问题,可采用HTTPS承载方式,事实上,也大多采用HTTPS的方式。为了可以维持一个长连接,双方会发送ping和pong消息。
  3. 通信结束,关闭连接

对于browser对同一个host只运行2条HTTP连接的限制,由于在握手后,协议转换为webSocket,不再是HTTP,即使是长连接,也不占2条的限制计算。

由于是IETF标准,浏览器支持,javascript和web container也都支持,在实现方面很简单,具体的消息交互的详细情况请参阅 RFC 6455。WebSocket的用途广泛,例如多人游戏,多人对话,股市实时报表,实时监控,媒体流等等。

握手过程

下面是 RFC 6455 的对握手过程的描述,为了方便阅读,将解释也附在旁边

(1)要求发送ws://server.example.com/chat的请求。ws(80)对应HTTP,wss(443)对应HTTPS,浏览器看到ws或者wss知道这是一个webSocket的请求,按握手过程发送HTTP请求。

(2)浏览器发送HTTP消息给server

 The handshake from the client looks as follows:  

   GET /chat HTTP/1.1
   Host: server.example.com
   Upgrade: websocket                          要求进行协议更换为webScoket,见 RFC2616 14.24
   Connection: Upgrade                         要求进行协议更换,见 RFC2616 14.24
   Origin: http://example.com                  表明请求来自哪个网页,安全作用,防止跨域请求,只允许被批准的domain访问
   Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== 基于协议的一致性检查,浏览器随机产生key的BASE64
   Sec-WebSocket-Protocol: chat, superchat     可选header,表明承载在webScoket里面的自定义协议
   Sec-WebSocket-Version: 13                   webSocket支持的版本
(3)server响应101,完成握手
The handshake from the server looks as follows:

   HTTP/1.1 101 Switching Protocols
   Upgrade: websocket
   Connection: Upgrade
   Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= 请求key加上258EAFA5-E914-47DA-95CA-C5AB0DC85B11,SHA-1的BASE64
   Sec-WebSocket-Protocol: chat


相关链接: 我的Professional Java for Web Applications相关文章

你可能感兴趣的:(JAVA,读书笔记,愷风(Wei)之Java,for,Web学习笔记)