打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
了解 WebSocket 的功能

当今的万维网并未设计成一个实时媒介。 当通过诸如 SignalR 和 Comet 之类的临时库有效实现 Web 应用程序时,Web 应用程序通过传统轮询解决方案(通过 AJAX 实现,或者也可能是通过长轮询请求实现)给人以连续的感观印象。 对于大部分应用程序的需求,轮询是一个不错的解决方案,即便它可能存在客户端到服务器和服务器到客户端的延迟。 本文将探讨一种新的替代方法,称为 WebSocket。

随着 Web 和移动应用程序与社交媒体之间的集成程度越来越高,人们能够容忍的客户端/服务器交互中的延迟越来越低。 当您更新 Facebook 状态时,您希望该信息能立即被您的好友看到。 同样,当有人喜欢您发布的某个帖子时,您希望能够立即获得相应的通知。 今天,所有这些功能都是切实存在的,这也正是 Facebook 在世界范围内如此热门,以及社交网络现象遍地开花的原因之一。 所以,最终结果就是迫切需要开发人员开发出能够通过 Web 实现实时通信的解决方案和工具。

在 Web 客户端和服务器之间实现零滞后连接不仅仅需要 HTTP 协议。 这正是 WebSocket 协议所能提供的。当前存在针对 WebSocket 协议的互联网工程任务组标准;您可以在 bit.ly/va6qSS 上了解此标准的相关信息。 实现该协议的标准 API 已由万维网联盟 (W3C) 正式确立,以便浏览器支持该协议(请参见bit.ly/h1IsjB)。 规范处于“候选推荐”状态。

WebSocket 协议

新的 WebSocket 协议旨在解决 HTTP 协议的结构限制,该限制使得浏览器中托管的 Web 应用程序无法通过持久连接高效地与服务器保持连接。 WebSocket 协议允许通过单一 TCP 套接字在 Web 应用程序和 Web 服务器之间实现双向通信。 换句话说,该协议使得浏览器中托管的 Web 应用程序可以一直与 Web 端点保持连接,同时还能将成本(例如服务器的压力、内存和资源消耗)降到最低。 实际效果是数据和通知在浏览器和 Web 服务器之间能够无延迟地发送和接收,并且无需安排额外的请求。 不容置疑,WebSocket 协议为开发人员打开了一个全新的充满无限可能的世界,让基于轮询的小把戏和框架都成为了历史。 其实并不完全是这样。

当今的 WebSocket 应用

WebSocket 协议的浏览器支持将会很快得到改善,但是只有最新版本的浏览器支持 WebSocket。 不经常升级浏览器的用户(或者因严格的公司策略而不允许升级的用户)将会落伍。

这意味着开发人员不能简单地放弃基于 AJAX 轮询的代码或长轮询解决方案。 在这方面,请关注 SignalR(即将推出的 Microsoft 框架,用于在浏览器和 Web 服务器之间实现零延迟消息传递),它在抽象化持久性连接、支持时自动切换到 WebSocket,以及在任何其他情况下使用长轮询方面,效果非常不错。 我在近期的专栏中已经介绍了 SignalR,如果您还未试用过 SignalR,我再次邀请您尽早尝试一下。 SignalR 毋庸置疑是所有开发人员和 Web 应用程序首选的库和工具。

当今有谁支持 WebSocket?

图 1 简单地列出了目前大多数热门浏览器提供的 WebSocket 支持。

图 1 WebSocket 的浏览器支持

浏览器WebSocket 支持
Internet ExplorerInternet Explorer 10 将支持 WebSocket。 使用 JavaScript 和 HTML5 编写的 Metro 应用程序也将支持 WebSocket。
Firefox从 2011 年年中发布的第 6 版浏览器开始支持 WebSocket。 在很早以前的第 4 版中曾提供过一些支持,但是在第 5 版时却弃用了这些支持。
Chrome从 2011 年 9 月发布的第 14 版开始支持 WebSocket。
Opera在第 11 版中删除了对 WebSocket 的支持。
Safari支持早期版本的 WebSocket 协议。

除 Firefox 外,您可以使用编程的方式通过查看 window.WebSocket 对象来了解 WebSocket 支持。 对于 Firefox,您当前应该查看 MozWebSocket 对象。 您应该注意到,大多数 HTML5 相关的功能都可以在浏览器中通过诸如 Modernizr (modernizr.com) 的专用库的方式进行查看。 特别是,如果您将 Modernizr 库链接到页面,则下面是您需要编写的 JavaScript 代码:

  1.  
  2.           if (Modernizr.websockets)
  3. {
  4.   ...
  5.           }
  6.         

如果您想要开始使用 WebSocket 实现,那么 Modernizr 可能是当下一个非常不错的选择,因为它向您提供填充代码,在当前浏览器不支持指定功能时会自动插入该代码。

因此,WebSocket 功能魅力无穷,但当下供应商的支持尚不统一。 然而 Microsoft 在即将推出的 Internet Explorer 10,以及 IIS、ASP.NET、Windows Communication Foundation (WCF) 和 Windows Runtime (WinRT) 中广泛支持 WebSocket。 请注意,尚不存在官方的标准 API,因此早期支持会引起业内极大的关注。 现如今您最多只能通过某个抽象层使用 WebSocket。 如果您想更接近事物本质并编写您自己的用于打开和关闭 WebSocket 的代码,则可以选择 Modernizr。 如果您要寻找一种框架以便以持久方式透明地连接浏览器和 Web 端点,而无需知道太多的底层详细信息,那么 SignalR 是更好的选择。

WebSocket 协议简介

双向通信的 WebSocket 协议要求客户端和服务器应用程序都了解协议详细信息。 这意味着您需要调用符合 WebSocket 的端点的符合 WebSocket 的网页。

WebSocket 交互从一次握手开始,在这次握手中,双方(浏览器和服务器)互相确认它们想通过持久性连接通信的意图。 接下来,在两个方向上通过 TCP 发送大量消息包。 图 2 概述了 WebSocket 协议的工作方式。

 
图 2 WebSocket 协议架构

请注意,除了图 2 中显示的内容以外,当连接关闭时,两个端点会交换一个关闭帧以干净利落地关闭连接。初次握手包含一个客户端发送给 Web 服务器的普通 HTTP 请求。 请求是配置为升级请求的 HTTP GET:

          GET /chat HTTP/1.1Host: server.example.comUpgrade: websocketConnection: UpgradeSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==Origin: http://example.com        

在 HTTP 中,具有 Upgrade 标头的客户端请求表示客户端想请求服务器切换到其他协议。 通过 WebSocket 协议,发往服务器的升级请求包含一个唯一的密钥,服务器会将其破坏并返回,作为它接受升级请求的证据。 这是表示服务器理解 WebSocket 协议的实际证明。 下面是握手请求的示例响应:

          HTTP/1.1 101 WebSocket Protocol HandshakeUpgrade: websocketConnection: UpgradeSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=        

成功的状态代码始终是 101,而任何其他状态代码将解释为拒绝升级到 WebSocket 协议。 服务器将收到的密钥与固定的 GUID 字符串连接,并计算生成的字符串的哈希值。 然后将哈希值编码为 Base64 并通过 Sec-WebSocket-Accept 标头将其返回给客户端。

客户端还可以发送其他标头(例如 Sec-WebSocket--Protocol)以表示它愿意采用哪些子协议。 子协议是在基本 WebSocket 协议基础之上构建的应用程序级别协议。 如果服务器理解建议的某些子协议,那么它将选择一个子协议并通过同一标头将子协议名称发送回客户端。

握手之后,客户端和服务器可以通过 WebSocket 协议自由发送消息。 负载从一个表示操作正在执行的操作码开始。 这些操作码的其中之一(具体说就是 0x8)表示关闭会话的请求。 请注意,WebSocket 消息异步发送,所以发送请求不一定会立即收到响应,与在 HTTP 中一样。 使用 WebSocket 协议,您最好从客户端和服务器相互发送的常规消息方面进行思考,忘记传统的 HTTP 请求/响应模式。

WebSocket 端点常用的 URL 采用以下形式:

  1.  
  2.           var myWebSocket =
  3.     new WebSocket("ws://www.websocket.org");
  4.         

如果您想要保持安全套接字连接,则可以使用 wss 协议前缀(当存在中间媒介时,安全连接通常会更成功)。 最后,WebSocket 协议承认并解决跨域通信的问题。 WebSocket 客户端通常(但不总是)允许将请求发送至位于任何域的端点。 但是,接受还是拒绝握手请求的决定权在 WebSocket 服务器。

WebSocket API 简介

正如之前所提到的,W3C 当前正在标准化用于 WebSocket 协议的 API,各种浏览器也正在争取符合推出的各种草案的要求。 您应该了解,今天能够使用的任何代码可能无法在所有的浏览器中使用,更重要的是,当同一浏览器的新版本问世时,甚至无法保证这些代码能够在该同一浏览器中使用。 在任何情况下,只要您具有有效的 WebSocket 代码,您基本上就完成得差不多了,因为将来可能需要做出的任何更改可能都只是微小改动。

如果您想要试用 WebSocket 协议,可以使用支持该协议的浏览器访问 websocket.org。 例如,您可以使用 Internet Explorer 10 的预览版或 Google Chrome 的最新版本。 图 3 显示 Fiddler 跟踪的握手过程。

 
图 3 浏览器和服务器之间的实际握手过程

实际上,当前版本的 Fiddler(版本 2.3.x)仅捕获 HTTP 流量。 不过,处理 WebSocket 流量的 Fiddler 新版本当前处于 Beta 阶段。

WebSocket API 相当简单。 在浏览器端,您需要创建 WebSocket 浏览器类的实例。 该类公开您希望具有其相应处理程序的大量相关事件:

  1.  
  2.           var wsUri = " ws://echo.websocket.org/";
  3. websocket = new WebSocket(wsUri);
  4. websocket.onopen = function(evt) { onOpen(evt) };
  5. websocket.onmessage = function(evt) { onMessage(evt) };
  6. websocket.onclose = function(evt) { onClose(evt) };
  7. websocket.onerror = function(evt) { onError(evt) };
  8.         

建立连接时触发 onopen 事件。 每当客户端收到来自服务器的消息时都会触发 onmessage 事件。 关闭连接时触发 onclose。 最后,发生错误时触发 onerror。

要向服务器发送消息,您只需要调用 send 方法即可,如下所示:

  1.  
  2.           var message = "Cutting Edge test: " +
  3.   new Date().toString();
  4. websocket.send(message);
  5.         

图 4 显示一个示例页面,该页面是根据 websocket.org 网站上找到的回显示例改写的。 在该示例中,服务器只是将收到的消息回显给客户端。

 
图 4 WebSocket 协议的实际应用

如果您对 Internet Explorer 10 的 WebSocket 编程感兴趣,请参见 bit.ly/GNYWFh

WebSocket 的服务器端

在本文中,我主要介绍了 WebSocket 协议客户端方面的事项。 有一点应该清楚,要使用 WebSocket 客户端,您需要能够理解请求并能适当回复的符合 WebSocket 标准的相应服务器。 构建 WebSocket 服务器的框架已开始出现。 例如,您可以尝试用于 Java 和 Node.js 的 Socket.IO (socket.io)。 如果您要寻找某些 Microsoft .NET Framework 材料,不妨查看一下 The Code Project 中的“Web 套接字服务器”,网址为bit.ly/lc0rjt 此外,IIS、ASP.NET 和 WCF 中提供面向 WebSocket 的 Microsoft 服务器支持。 有关详细信息,您可以观看第 9 频道的视频“使用 IIS、ASP.NET 和 WCF 通过 WebSocket 构建实时的 Web 应用程序”(bit.ly/rnYaw5)。

Sliced Bread、Hot Water 和 WebSocket

正如很多人所说的,WebSocket 是继切片面包和热水之后最有用的发明。 在了解 WebSocket 之后,您就会禁不住想知道如果没有这些发明创造,软件世界该如何繁荣昌盛。 WebSocket 对于许多应用程序都很有用,虽然不是对所有的应用程序都有用。 对于即时消息传递至关重要的任何应用程序,您都可以认真考虑构建 WebSocket 服务器和大量客户端,例如 Web、移动设备甚至是台式机。 游戏和现场播放应用程序是能够从 WebSocket 协议获得极大利益的另外两个行业领域。 是的,WebSocket 的确是继热水之后最棒的发明!

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
web前端笔记WebSocket协议
一文吃透 WebSocket 原理
使用 HTML5 WebSocket 构建实时 Web 应用
SignalR 2.0 系列: SignalR简介
SignalR新手系列教程详解(一)
webSocket和http的区别
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服