Java中的WebSocket(上)

本文根据网上各位大神的博文总结而来,参考了一篇写的很好的博文,点击此处可跳转到该博文。

1 引

      在web应用中,其交互过程是客户端通过浏览器向服务器发出一个请求,服务器接收到请求后进行处理然后将结果返回给浏览器,浏览器解析结果并呈现信息给用户。当前越来越多的应用希望能够及时获取服务端提供的数据,甚至希望能够达到接近实时的数据交换,这些应用常见的主要由社交网络的即时通讯、Web导航应用中的地理位置获取、金融证券的实时信息等。传统的请求-响应模式的Web开发处理这个问题时,通常采用的方案有轮询、长轮询、流等。

  • 轮询:这是最早的一种实现实时 Web 应用的方案,客户端通过一定的时间间隔以频繁请求的方式向服务器发送请求,来保持客户端和服务器端的数据同步。这种方式一方面会有许多不必要的请求,而且浪费带宽。
  • 长轮询:是对定时轮询的改进和提高,目地是为了降低无效的网络传输。当服务器端没有数据更新的时候,连接会保持一段时间周期直到数据或状态改变或者 时间过期,通过这种机制来减少无效的客户端和服务器间的交互。当然,如果服务端的数据变更非常频繁的话,这种机制和定时轮询比较起来没有本质上的性能的提高
  • 所谓流是指客户端在页面之下向服务端发起一个长连接请求,服务端收到这个请求后响应它并不断更新连接状态,以确保这个连接在客户端与服务端之间一直有效。服务端可以通过这个连接将数据主动推送到客户端。显然,这种方案实现起来相对比较麻烦,而且可能被防火墙阻断。

       上述方式其实并不是真正的实时技术,只是使用了一种技巧来实现的模拟实时。在每次客户端和服务器端交互的时候都是一次 HTTP 的请求和应答的过程,而每一次的 HTTP 请求和应答都带有完整的 HTTP 头信息,这就增加了每次传输的数据量。


 2 WebSocket运行机制

     在上述背景下,基于HTML5规范的,有WebTCP之称的WebSocket出现了。早期 HTML5 并没有形成业界统一的规范,各个浏览器和应用服务器厂商有着各异的类似实现,如 IBM 的 MQTT,Comet 开源框架等,直到 2014 年,HTML5 在 IBM、微软、Google 等巨头的推动和协作下正式从草案落实为实际标准规范,各个应用服务器及浏览器厂商逐步开始统一,在 JavaEE7 中也实现了 WebSocket 协议,从而无论是客户端还是服务端的 WebSocket 都已完备,可以查阅HTML5 规范获得最新的 HTML 协议规范及 WebSocket 支持。

    WebSocket 是 HTML5 一种新的协议。本质是先通过HTTP/HTTPS协议进行握手后创建一个用于交换数据的TCP连接,它实现了浏览器与服务器全双工通信,能更好的节省服务器资源和带宽并达到实时通讯,它建立在 TCP 之上,同 HTTP 一样通过 TCP 来传输数据,但是它和 HTTP 存在不同,这主要包括两个方面,

       一是WebSocket 是一种双向通信协议,在建立连接后,WebSocket 服务器和 Browser/Client Agent 都能主动的向对方发送或接收数据,就像 Socket 一样。相对于传统 HTTP 每次请求-应答都需要客户端与服务端建立连接的模式,WebSocket 是类似 Socket 的 TCP 长连接的通讯模式,一旦 WebSocket 连接建立后,后续数据都以帧序列的形式传输。在客户端断开 WebSocket 连接或 Server 端断掉连接前,不需要客户端和服务端重新发起连接请求。
     二是客户端和服务端交互的报文方面WebSocket 通讯与传统 HTTP 也是不同的。在客户端,new WebSocket 实例化一个新的 WebSocket 客户端对象,连接类似 ws://ip:port/path 的服务端 WebSocket URL,WebSocket 客户端对象会自动解析并识别为 WebSocket 请求,从而连接服务端端口,执行双方握手过程,客户端发送数据格式类似:

  • WebSocket客户端连接报文:

GET /webfin/websocket/ HTTP/1.1
Host: localhost
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: xqBt3ImNzJbYqRINxEFlkg==
Origin: http://localhost:8080
Sec-WebSocket-Version: 13

       客户端发起的 WebSocket 连接报文类似传统 HTTP 报文,”Upgrade:websocket”参数值表明这是 WebSocket 类型请求,这个请求的目的就是要将客户端和服务器端的通讯协议从 HTTP 协议升级到 WebSocket 协议。“Sec-WebSocket-Key”是 WebSocket 客户端发送的一个 base64 编码的密文,要求服务端必须返回一个对应加密的“Sec-WebSocket-Accept”应答,否则客户端会抛出“Error during WebSocket handshake”错误,并关闭连接。

  • 服务端收到报文后返回的数据格式类似:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: K7DJLdLooIwIG/MOpvWFB3y3FE8=
       "Sec-WebSocket-Accept”的值是服务端采用与客户端一致的密钥计算出来后返回客户端的,“HTTP/1.1 101 Switching Protocols”表示服务端接受 WebSocket 协议的客户端连接,经过这样的请求-响应处理后,客户端服务端的 WebSocket 连接握手成功, 后续就可以进行 TCP 通讯。在开发方面,WebSocket API 相对简单,只需要实例化 WebSocket,创建连接,然后服务端和客户端就可以相互发送和响应消息。

3 WebSocket客户端与服务器的实现

       WebSocket 的实现分为客户端和服务端两部分,客户端(通常为浏览器)发出 WebSocket 连接请求,服务端响应,实现类似 TCP 握手的动作,从而在浏览器客户端和 WebSocket 服务端之间形成一条 HTTP 长连接快速通道。两者之间后续进行直接的数据互相传送,不再需要发起连接和相应。

  • 服务端API

     WebSocket 服务端在各个主流应用服务器厂商中已基本获得符合 JEE JSR356 标准规范 API 的支持。以下列举了部分常见的商用及开源应用服务器对 WebSocket Server 端的支持情况:

厂商应用服务器备注
IBMWebSphereWebSphere 8.0 以上版本支持,7.X 之前版本结合 MQTT 支持类似的 HTTP 长连接
甲骨文WebLogicWebLogic 12c 支持,11g 及 10g 版本通过 HTTP Publish 支持类似的 HTTP 长连接
微软IISIIS 7.0+支持
ApacheTomcatTomcat 7.0.5+支持,7.0.2X 及 7.0.3X 通过自定义 API 支持
 JettyJetty 7.0+支持







       服务端代码需要用户来编写,目前市场上开源的有:Kaazing WebSocket Gateway(一个 Java 实现的 WebSocket Server);mod_pywebsocket(一个 Python 实现的 WebSocket Server);Netty(一个 Java 实现的网络框架其中包括了对 WebSocket 的支持); node.js(一个 Server 端的 JavaScript 框架提供了对 WebSocket 的支持)等。 

  • 客户端API

       对于 WebSocket 客户端,主流的浏览器(包括 PC 和移动终端)现已都支持标准的 HTML5 的 WebSocket API,这意味着客户端的 WebSocket JavaScirpt 脚本具备良好的一致性和跨平台特性。客户端 WebSocket API 基本上已经在各个主流浏览器厂商中实现了统一,因此使用标准 HTML5 定义的 WebSocket 客户端的 JavaScript API 即可



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值