此條目需要更新 。 (2018年8月11日 ) 請更新本文以反映近況和新增内容。完成修改後請移除本模板。
WebSocket 是一种网络传输协议 ,可在单个TCP 连接上进行全双工 通信,位于OSI模型 的应用层 。WebSocket协议在2011年由IETF 标准化为RFC 6455 ,后由RFC 7936 补充规范。Web IDL 中的WebSocket API由W3C 标准化。
WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就可以建立持久性的连接,并进行双向数据传输。
简介
WebSocket是一种与HTTP 不同的协议。两者都位于OSI模型 的应用层 ,并且都依赖于传输层 的TCP协议。
虽然它们不同,但是RFC 6455中规定:it is designed to work over HTTP ports 80 and 443 as well as to support HTTP proxies and intermediaries
(WebSocket通过HTTP端口80和443进行工作,并支持HTTP代理和中介),从而使其与HTTP协议兼容。
为了实现兼容性,WebSocket握手使用HTTP Upgrade头[ 1] 从HTTP协议更改为WebSocket协议。
WebSocket协议支持Web浏览器 (或其他客户端应用程序)与Web服务器 之间的交互,具有较低的开销,便于实现客户端与服务器的实时数据传输。
服务器可以通过标准化的方式来实现,而无需客户端首先请求内容,并允许消息在保持连接打开的同时来回传递。通过这种方式,可以在客户端和服务器之间进行双向持续对话。
通信通过TCP端口80或443完成,这在防火墙阻止非Web网络连接的环境下是有益的。另外,Comet 之类的技术以非标准化的方式实现了类似的双向通信。
大多数浏览器都支持该协议,包括Google Chrome 、Firefox 、Safari 、Microsoft Edge 、Internet Explorer 和Opera 。
与HTTP不同,WebSocket提供全双工通信。[ 2] [ 3] 此外,WebSocket还可以在TCP之上实现消息流。TCP单独处理字节流,没有固有的消息概念。
在WebSocket之前,使用Comet可以实现全双工通信。但是Comet存在TCP握手和HTTP头的开销,因此对于小消息来说效率很低。WebSocket协议旨在解决这些问题。
WebSocket协议规范将ws
(WebSocket)和wss
(WebSocket Secure)定义为两个新的统一资源标识符 (URI)方案[ 4] ,分别对应明文和加密连接。除了方案名称和片段ID(不支持#
)之外,其余的URI组件都被定义为此URI的通用语法。[ 5]
使用浏览器开发人员工具,开发人员可以检查WebSocket握手以及WebSocket框架。[ 6]
历史
WebSocket最初在HTML5 规范中被引用为TCPConnection,作为基于TCP的套接字API的占位符。[ 7] 2008年6月,Michael Carter 进行了一系列讨论,最终形成了称为WebSocket的协议。[ 8]
“WebSocket”这个名字是Ian Hickson和Michael Carter之后在 #whatwg IRC 聊天室创造的[ 9] ,随后由Ian Hickson撰写并列入HTML5规范,并在Michael Carter的Cometdaily博客上宣布[ 10] 。
2009年12月,Google Chrome 4是第一个提供标准支持的浏览器,默认情况下启用了WebSocket。[ 11] WebSocket协议的开发随后于2010年2月从W3C和WHATWG小组转移到IETF,并在Ian Hickson的指导下进行了两次修订。[ 12]
该协议被多个浏览器默认支持并启用后,RFC 于2011年12月在Ian Fette下完成。[ 13]
背景
早期,很多网站为了实现推送技术 ,所用的技术都是轮询 。轮询是指由浏览器每隔一段时间(如每秒)向服务器发出HTTP请求,然后服务器返回最新的数据给客户端。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求与回复可能会包含较长的头部 ,其中真正有效的数据可能只是很小的一部分,所以这样会消耗很多带宽资源。
比较新的轮询技术是Comet 。这种技术虽然可以实现双向通信,但仍然需要反复发出请求。而且在Comet中普遍采用的HTTP长连接 也会消耗服务器资源。
在这种情况下,HTML5 定义了WebSocket协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。
Websocket使用ws
或wss
的统一资源标志符 (URI)。其中wss
表示使用了TLS 的Websocket。如:
ws://example.com/wsapi
wss://secure.example.com/wsapi
Websocket与HTTP和HTTPS使用相同的TCP端口 ,可以绕过大多数防火墙 的限制。默认情况下,Websocket协议使用80端口;运行在TLS之上时,默认使用443端口。
优点
较少的控制开销。在连接建立后,服务器和客户端之间交换数据时,用于协议控制的数据包头部相对较小。在不包含扩展的情况下,对于服务器到客户端的内容,此头部大小只有2至10字节 (和数据包长度有关);对于客户端到服务器的内容,此头部还需要加上额外的4字节的掩码 。相对于HTTP请求每次都要携带完整的头部,此项开销显著减少了。
更强的实时性。由于协议是全双工的,所以服务器可以随时主动给客户端下发数据。相对于HTTP请求需要等待客户端发起请求服务端才能响应,延迟明显更少;即使是和Comet等类似的长轮询 比较,其也能在短时间内更多次地传递数据。
保持连接状态。与HTTP不同的是,Websocket需要先建立连接,这就使得其成为一种有状态的协议,之后通信时可以省略部分状态信息。而HTTP请求可能需要在每个请求都携带状态信息(如身份认证等)。
更好的二进制支持。Websocket定义了二进制 帧,相对HTTP,可以更轻松地处理二进制内容。
可以支持扩展。Websocket定义了扩展,用户可以扩展协议、实现部分自定义的子协议。如部分浏览器支持压缩 等。
更好的压缩效果。相对于HTTP压缩 ,Websocket在适当的扩展支持下,可以沿用之前内容的上下文 ,在传递类似的数据时,可以显著地提高压缩率。[ 14]
握手协议
WebSocket 是独立的、建立在TCP上的协议。
Websocket 通过 HTTP /1.1 协议的101状态码 进行握手。
为了建立Websocket连接,需要通过浏览器发出请求,之后服务器进行回应,这个过程通常称为“握手 ”(Handshaking)。
例子
一个典型的Websocket握手请求如下[ 15] :
客户端请求:
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
服务器回应:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat
字段说明
Connection必须设置Upgrade,表示客户端希望连接升级。
Upgrade字段必须设置Websocket,表示希望升级到Websocket协议。
Sec-WebSocket-Key是随机的字符串,服务器端会用这些数据来构造出一个SHA-1的信息摘要。把“Sec-WebSocket-Key”加上一个特殊字符串“258EAFA5-E914-47DA-95CA-C5AB0DC85B11”,然后计算SHA-1 摘要,之后进行Base64 编码,将结果做为“Sec-WebSocket-Accept”头的值,返回给客户端。如此操作,可以尽量避免普通HTTP请求被误认为Websocket协议。
Sec-WebSocket-Version 表示支持的Websocket版本。RFC6455要求使用的版本是13,之前草案的版本均应当弃用。
Origin字段是必须的。如果缺少origin字段,WebSocket服务器需要回复HTTP 403 状态码(禁止访问)。[ 16]
其他一些定义在HTTP协议中的字段,如Cookie 等,也可以在Websocket中使用。
浏览器支持
WebSocket协议的安全版本在Firefox 6[ 17] 、Safari 6、Google Chrome 14[ 18] 、Opera 12.10和Internet Explorer 10中实现。[ 19] 详细的协议测试套件报告[ 20] 列出了这些浏览器与特定协议方面的一致性。
Opera 11和Safari 5中实现了较旧的,不太安全的协议版本,以及iOS 4.2中的Safari移动版本。[ 21] OS7中的BlackBerry Browser实现了WebSockets。[ 22] 由于存在漏洞,它在Firefox 4和5[ 23] 以及Opera 11中被禁用。[ 24]
所有最新的浏览器支持最新规范(RFC 6455 )的WebSocket协议。一个详细的测试报告[ 20] 列出了这些浏览器支持的Websocket版本。
1 基于Gecko 6–10版本的浏览器的WebSocket对象为“mozwebsocket”,[ 33] 需要添加额外的代码。
服务器
在服务器方面,网上都有不同对websocket支持的服务器:
参考资料
^ Ian Fette; Alexey Melnikov. Relationship to TCP and HTTP . RFC 6455 The WebSocket Protocol . IETF . December 2011: sec. 1.7. RFC 6455.
^ Glossary:WebSockets . Mozilla Developer Network. 2015 [2019-05-09 ] . (原始内容存档 于2016-09-14).
^ HTML5 WebSocket: A Quantum Leap in Scalability for the Web . [2019-05-09 ] . (原始内容 存档于2021-04-01).
^ Graham Klyne (编). IANA Uniform Resource Identifer (URI) Schemes . Internet Assigned Numbers Authority . 2011-11-14 [2011-12-10 ] . (原始内容存档 于2013-04-25).
^ Ian Fette; Alexey Melnikov. WebSocket URIs . RFC 6455 The WebSocket Protocol . IETF . December 2011: sec. 3. RFC 6455.
^ Wang, Vanessa; Salim, Frank; Moskovits, Peter. APPENDIX A: WebSocket Frame Inspection with Google Chrome Developer Tools . The Definitive Guide to HTML5 WebSocket. Apress. February 2013 [7 April 2013] . ISBN 978-1-4302-4740-1 . (原始内容存档 于2015-12-31).
^ HTML 5 . www.w3.org. [2016-04-17 ] . (原始内容存档 于2016-09-16).
^ [whatwg] TCPConnection feedback from Michael Carter on 2008-06-18 (whatwg.org from June 2008) . lists.w3.org. [2016-04-17 ] . (原始内容存档 于2016-04-27).
^ IRC logs: freenode / #whatwg / 20080618 . krijnhoetmer.nl. [2016-04-18 ] . (原始内容存档 于2016-08-21).
^ Comet Daily » Blog Archive » Independence Day: HTML5 WebSocket Liberates Comet From Hacks . [2016-04-17 ] . (原始内容 存档于2016-04-23).
^ Web Sockets Now Available In Google Chrome . Chromium Blog. [2016-04-17 ] . (原始内容 存档于2021-12-09) (美国英语) .
^ <ian@hixie.ch>, Ian Hickson. The WebSocket protocol . tools.ietf.org. [2016-04-17 ] . (原始内容存档 于2017-03-17).
^ <ian@hixie.ch>, Ian Hickson. The WebSocket protocol . tools.ietf.org. [2016-04-17 ] . (原始内容存档 于2017-03-06).
^ 存档副本 . [2017-01-17 ] . (原始内容 存档于2020-11-11).
^ 存档副本 . [2019-05-09 ] . (原始内容存档 于2017-03-06).
^ RFC 6455 - The WebSocket Protocol . IETF Tools. [2019-05-09 ] . (原始内容 存档于2017-03-06). Servers that are not intended to process input from any web page but only for certain sites SHOULD verify the |Origin| field is an origin they expect. If the origin indicated is unacceptable to the server, then it SHOULD respond to the WebSocket handshake with a reply containing HTTP 403 Forbidden status code.
^ Dirkjan Ochtman. WebSocket enabled in Firefox 6 . Mozilla.org. May 27, 2011 [2011-06-30 ] . (原始内容 存档于2012-05-26).
^ Chromium Web Platform Status . [2011-08-03 ] . (原始内容存档 于2017-03-04).
^ WebSockets (Windows) . Microsoft. 2012-09-28 [2012-11-07 ] . (原始内容存档 于2015-03-25).
^ 20.0 20.1 WebSockets Protocol Test Report . Tavendo.de. 2011-10-27 [2011-12-10 ] . (原始内容 存档于2016-09-22).
^ Katie Marsal. Apple adds accelerometer, WebSockets support to Safari in iOS 4.2 . AppleInsider.com. November 23, 2010 [2011-05-09 ] . (原始内容存档 于2013-07-17).
^ Web Sockets API . BlackBerry . [8 July 2011] . (原始内容 存档于2011-06-10).
^ Chris Heilmann. WebSocket disabled in Firefox 4 . Hacks.Mozilla.org. December 8, 2010 [2011-05-09 ] . (原始内容存档 于2017-03-06).
^ Aleksander Aas. Regarding WebSocket . My Opera Blog. December 10, 2010 [2011-05-09 ] . (原始内容存档 于2010-12-15).
^ WebSockets (support in Firefox) . Developer.mozilla.org. 2011-09-30 [2011-12-10 ] . (原始内容 存档于2012-05-26).
^ Bug 640003 - WebSockets - upgrade to ietf-06 . Bugzilla.mozilla.org. [2011-12-10 ] . (原始内容 存档于2021-04-01).
^ WebSockets - upgrade to ietf-07 (页面存档备份 ,存于互联网档案馆 )>
^ Chromium bug 64470 . Code.google.com. 2010-11-25 [2011-12-10 ] . (原始内容 存档于2015-12-31).
^ WebSockets in Windows Consumer Preview . IE Engineering Team. 2012-03-19 [2012-07-23 ] . (原始内容存档 于2012-08-07).
^ WebKit Changeset 97247: WebSocket: Update WebSocket protocol to hybi-17 . Trac.webkit.org. [2011-12-10 ] . (原始内容 存档于2015-12-31).
^ A hot Opera 12.50 summer-time snapshot . Opera Developer News. [2012-08-03 ] . (原始内容 存档于2012-08-05).
^ Compatibility tables for support of HTML5, CSS3, SVG and more in desktop and mobile browsers . caniuse.com. [2014-02-10 ] . (原始内容存档 于2017-04-08).
^ WebSockets - MDN . Developer.mozilla.org. 2011-09-30 [2011-12-10 ] . (原始内容 存档于2012-05-26).
網頁技術與標準
文档呈现语言 样式格式描述语言 动态网页技术 用戶端互動技术 用戶端手稿語言 标识定位语言 文档纲要语言