WebSocket 详解(48页).doc
《WebSocket 详解(48页).doc》由会员分享,可在线阅读,更多相关《WebSocket 详解(48页).doc(49页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、-WebSocket 详解本文介绍了 HTML5 WebSocket 的由来,运作机制及客户端和服务端的 API 实现,重点介绍服务端(基于 Tomcat7)及客户端(基于浏览器原生 HTML5 API)实现的详细步骤;并通过实际客户案例描述了客户端如何在 WebSocket 架构下使用 HTTP 长连接与服务器实现实时通信及消息推送的功能,读者通过阅读本文中案例示例代码的实现,能够更深刻理解 WebSocket 框架的技术原理和开发方法。WebSocket 前世今生众所周知,Web 应用的交互过程通常是客户端通过浏览器发出一个请求,服务器端接收请求后进行处理并返回结果给客户端,客户端浏览器将
2、信息呈现,这种机制对于信息变化不是特别频繁的应用尚可,但对于实时要求高、海量并发的应用来说显得捉襟见肘,尤其在当前业界移动互联网蓬勃发展的趋势下,高并发与用户实时响应是 Web 应用经常面临的问题,比如金融证券的实时信息,Web 导航应用中的地理位置获取,社交网络的实时消息推送等。传统的请求-响应模式的 Web 开发在处理此类业务场景时,通常采用实时通讯方案,常见的是: 轮询,原理简单易懂,就是客户端通过一定的时间间隔以频繁请求的方式向服务器发送请求,来保持客户端和服务器端的数据同步。问题很明显,当客户端以固定频率向服务器端发送请求时,服务器端的数据可能并没有更新,带来很多无谓请求,浪费带宽,
3、效率低下。 基于 Flash,AdobeFlash 通过自己的 Socket 实现完成数据交换,再利用 Flash 暴露出相应的接口为 JavaScript 调用,从而达到实时传输目的。此方式比轮询要高效,且因为 Flash 安装率高,应用场景比较广泛,但在移动互联网终端上 Flash 的支持并不好。IOS 系统中没有 Flash 的存在,在 Android 中虽然有 Flash 的支持,但实际的使用效果差强人意,且对移动设备的硬件配置要求较高。2012 年 Adobe 官方宣布不再支持 Android4.1+系统,宣告了 Flash 在移动终端上的死亡。从上文可以看出,传统 Web 模式在处
4、理高并发及实时性需求的时候,会遇到难以逾越的瓶颈,我们需要一种高效节能的双向通信机制来保证数据的实时传输。在此背景下,基于 HTML5 规范的、有 Web TCP 之称的 WebSocket 应运而生。早期 HTML5 并没有形成业界统一的规范,各个浏览器和应用服务器厂商有着各异的类似实现,如 IBM 的 MQTT,Comet 开源框架等,直到 2014 年,HTML5 在 IBM、微软、Google 等巨头的推动和协作下终于尘埃落地,正式从草案落实为实际标准规范,各个应用服务器及浏览器厂商逐步开始统一,在 JavaEE7 中也实现了 WebSocket 协议,从而无论是客户端还是服务端的 W
5、ebSocket 都已完备,读者可以查阅,熟悉新的 HTML 协议规范及 WebSocket 支持。WebSocket 机制以下简要介绍一下 WebSocket 的原理及运行机制。WebSocket 是 HTML5 一种新的协议。它实现了浏览器与服务器全双工通信,能更好的节省服务器资源和带宽并达到实时通讯,它建立在 TCP 之上,同 HTTP 一样通过 TCP 来传输数据,但是它和 HTTP 最大不同是: WebSocket 是一种双向通信协议,在建立连接后,WebSocket 服务器和 Browser/Client Agent 都能主动的向对方发送或接收数据,就像 Socket 一样; We
6、bSocket 需要类似 TCP 的客户端和服务器端通过握手连接,连接成功后才能相互通信。非 WebSocket 模式传统 HTTP 客户端与服务器的交互如下图所示:图 1. 传统 HTTP 请求响应客户端服务器交互图使用 WebSocket 模式客户端与服务器的交互如下图:图 2.WebSocket 请求响应客户端服务器交互图上图对比可以看出,相对于传统 HTTP 每次请求-应答都需要客户端与服务端建立连接的模式,WebSocket 是类似 Socket 的 TCP 长连接的通讯模式,一旦 WebSocket 连接建立后,后续数据都以帧序列的形式传输。在客户端断开 WebSocket 连接或
7、 Server 端断掉连接前,不需要客户端和服务端重新发起连接请求。在海量并发及客户端与服务器交互负载流量大的情况下,极大的节省了网络带宽资源的消耗,有明显的性能优势,且客户端发送和接受消息是在同一个持久连接上发起,实时性优势明显。我们再通过客户端和服务端交互的报文看一下 WebSocket 通讯与传统 HTTP 的不同:在客户端,new WebSocket 实例化一个新的 WebSocket 客户端对象,连接类似 ws:/yourdomain:port/path 的服务端 WebSocket URL,WebSocket 客户端对象会自动解析并识别为 WebSocket 请求,从而连接服务端端
8、口,执行双方握手过程,客户端发送数据格式类似:清单 1.WebSocket 客户端连接报文GET /webfin/websocket/ HTTP/1.1Host: localhostUpgrade: websocketConnection: UpgradeSec-WebSocket-Key: xqBt3ImNzJbYqRINxEFlkg=Origin: :8080Sec-WebSocket-Version: 13可以看到,客户端发起的 WebSocket 连接报文类似传统 HTTP 报文,”Upgrade:websocket”参数值表明这是 WebSocket 类型请求,“Sec-WebSoc
9、ket-Key”是 WebSocket 客户端发送的一个 base64 编码的密文,要求服务端必须返回一个对应加密的“Sec-WebSocket-Accept”应答,否则客户端会抛出“Error during WebSocket handshake”错误,并关闭连接。服务端收到报文后返回的数据格式类似:清单 2.WebSocket 服务端响应报文HTTP/1.1 101 Switching ProtocolsUpgrade: websocketConnection: UpgradeSec-WebSocket-Accept: K7DJLdLooIwIG/MOpvWFB3y3FE8=“Sec-We
10、bSocket-Accept”的值是服务端采用与客户端一致的密钥计算出来后返回客户端的,“HTTP/1.1 101 Switching Protocols”表示服务端接受 WebSocket 协议的客户端连接,经过这样的请求-响应处理后,客户端服务端的 WebSocket 连接握手成功, 后续就可以进行 TCP 通讯了。读者可以查阅了解 WebSocket 客户端和服务端更详细的交互数据格式。在开发方面,WebSocket API 也十分简单,我们只需要实例化 WebSocket,创建连接,然后服务端和客户端就可以相互发送和响应消息,在下文 WebSocket 实现及案例分析部分,可以看到详细
11、的 WebSocket API 及代码实现。WebSocket 实现如上文所述,WebSocket 的实现分为客户端和服务端两部分,客户端(通常为浏览器)发出 WebSocket 连接请求,服务端响应,实现类似 TCP 握手的动作,从而在浏览器客户端和 WebSocket 服务端之间形成一条 HTTP 长连接快速通道。两者之间后续进行直接的数据互相传送,不再需要发起连接和相应。以下简要描述 WebSocket 服务端 API 及客户端 API。WebSocket 服务端 APIWebSocket 服务端在各个主流应用服务器厂商中已基本获得符合 JEE JSR356 标准规范 API 的支持(详
12、见),以下列举了部分常见的商用及开源应用服务器对 WebSocket Server 端的支持情况:表 1.WebSocket 服务端支持厂商应用服务器备注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支持以下我们使
13、用 Tomcat7.0.5 版本的服务端示例代码说明 WebSocket 服务端的实现:JSR356 的 WebSocket 规范使用 javax.websocket.*的 API,可以将一个普通 Java 对象(POJO)使用 ServerEndpoint 注释作为 WebSocket 服务器的端点,代码示例如下:清单 3.WebSocket 服务端 API 示例 ServerEndpoint(/echo) public class EchoEndpoint OnOpen public void onOpen(Session session) throws IOException /以下代码
14、省略. OnMessage public String onMessage(String message) /以下代码省略. Message(maxMessageSize=6) public void receiveMessage(String s) /以下代码省略. OnError public void onError(Throwable t) /以下代码省略. OnClose public void onClose(Session session, CloseReason reason) /以下代码省略. 代码解释:上文的简洁代码即建立了一个 WebSocket 的服务端,ServerE
15、ndpoint(/echo) 的 annotation 注释端点表示将 WebSocket 服务端运行在 ws:/Server 端 IP 或域名:Server 端口/websockets/echo 的访问端点,客户端浏览器已经可以对 WebSocket 客户端 API 发起 HTTP 长连接了。使用 ServerEndpoint 注释的类必须有一个公共的无参数构造函数,onMessage 注解的 Java 方法用于接收传入的 WebSocket 信息,这个信息可以是文本格式,也可以是二进制格式。OnOpen 在这个端点一个新的连接建立时被调用。参数提供了连接的另一端的更多细节。Session
16、表明两个 WebSocket 端点对话连接的另一端,可以理解为类似 HTTPSession 的概念。OnClose 在连接被终止时调用。参数 closeReason 可封装更多细节,如为什么一个 WebSocket 连接关闭。更高级的定制如 Message 注释,MaxMessageSize 属性可以被用来定义消息字节最大限制,在示例程序中,如果超过 6 个字节的信息被接收,就报告错误和连接关闭。注意:早期不同应用服务器支持的 WebSocket 方式不尽相同,即使同一厂商,不同版本也有细微差别,如 Tomcat 服务器 7.0.5 以上的版本都是标准 JSR356 规范实现,而 7.0.2x
17、/7.0.3X 的版本使用自定义 API (WebSocketServlet 和 StreamInbound, 前者是一个容器,用来初始化 WebSocket 环境;后者是用来具体处理 WebSocket 请求和响应,详见案例分析部分),且 Tomcat7.0.3x 与 7.0.2x 的 createWebSocketInbound 方法的定义不同,增加了一个 HttpServletRequest 参数,使得可以从 request 参数中获取更多 WebSocket 客户端的信息,如下代码所示:清单 4.Tomcat7.0.3X 版本 WebSocket APIpublic class Ech
18、oServlet extends WebSocketServlet Overrideprotected StreamInbound createWebSocketInbound(String subProtocol,HttpServletRequest request) /以下代码省略.return new MessageInbound() /以下代码省略.protected void onBinaryMessage(ByteBuffer buffer)throws IOException /以下代码省略.protected void onTextMessage(CharBuffer buff
19、er) throws IOException getWsOutbound().writeTextMessage(buffer); /以下代码省略.;因此选择 WebSocket 的 Server 端重点需要选择其版本,通常情况下,更新的版本对 WebSocket 的支持是标准 JSR 规范 API,但也要考虑开发易用性及老版本程序移植性等方面的问题,如下文所述的客户案例,就是因为客户要求统一应用服务器版本所以使用的 Tomcat 7.0.3X 版本的 WebSocketServlet 实现,而不是 JSR356 的 ServerEndpoint 注释端点。WebSocket 客户端 API对于
20、 WebSocket 客户端,主流的浏览器(包括 PC 和移动终端)现已都支持标准的 HTML5 的 WebSocket API,这意味着客户端的 WebSocket JavaScirpt 脚本具备良好的一致性和跨平台特性,以下列举了常见的浏览器厂商对 WebSocket 的支持情况:表 2.WebSocket 客户端支持浏览器支持情况ChromeChrome version 4+支持FirefoxFirefox version 5+支持IEIE version 10+支持SafariIOS 5+支持Android BrowerAndroid 4.5+支持客户端 WebSocket API 基
21、本上已经在各个主流浏览器厂商中实现了统一,因此使用标准 HTML5 定义的 WebSocket 客户端的 JavaScript API 即可,当然也可以使用业界满足 WebSocket 标准规范的开源框架,如 Socket.io。以下以一段代码示例说明 WebSocket 的客户端实现:清单 5.WebSocket 客户端 API 示例var ws = new WebSocket(“ws:/echo.websocket.org”); ws.onopen = function()ws.send(“Test!”); ; ws.onmessage = function(evt)console.log
22、(evt.data);ws.close(); ws.onclose = function(evt)console.log(“WebSocketClosed!”); ws.onerror = function(evt)console.log(“WebSocketError!”);第一行代码是在申请一个 WebSocket 对象,参数是需要连接的服务器端的地址,同 HTTP 协议开头一样,WebSocket 协议的 URL 使用 ws:/开头,另外安全的 WebSocket 协议使用 wss:/开头。第二行到第五行为 WebSocket 对象注册消息的处理函数,WebSocket 对象一共支持四个
23、消息 onopen, onmessage, onclose 和 onerror,有了这 4 个事件,我们就可以很容易很轻松的驾驭 WebSocket。当 Browser 和 WebSocketServer 连接成功后,会触发 onopen 消息;如果连接失败,发送、接收数据失败或者处理数据出现错误,browser 会触发 onerror 消息;当 Browser 接收到 WebSocketServer 发送过来的数据时,就会触发 onmessage 消息,参数 evt 中包含 Server 传输过来的数据;当 Browser 接收到 WebSocketServer 端发送的关闭连接请求时,就会
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- WebSocket 详解48页 详解 48
限制150内