WebSocket 学习

项目中以前已经使用过 websocket 进行一些和服务器的实时数据通讯,可是对于协议自己并不十分了解,也是借此机会学习一下并分享出来。html

OSI 位置?

应用层,和 Http 协议是同级关系java

为何须要 WebSocket ?

既然同 Http 协议是同层,为何还须要另外一个协议?它有什么好处?git

答案很简单,由于 HTTP 协议的设计之初就是:通讯只能由客户端发起。 举例来讲,咱们想了解当前的股票价格,只能是客户端向服务器发出请求,服务器返回查询结果。要想实时刷新股票的价格,这个 HTTP 协议搞起来就有点费劲了,由于 HTTP 协议作不到服务器主动向客户端推送信息。github

技术背景

这种单向请求的特色,注定了若是服务器有连续的状态变化,客户端要获知就很是麻烦。有没有什么办法能够解决双向通讯的问题呢?web

轮询

轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,而后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器须要不断的向服务器发出请求,然而HTTP请求可能包含较长的 头部 ,其中真正有效的数据可能只是很小的一部分,显然这样会浪费不少的带宽等资源。浏览器

Comet

Comet is a web application model in which a long-held HTTPS request allows a web server to push data to a browser, without the browser explicitly requesting it.安全

Comet is an umbrella term, encompassing multiple techniques for achieving this interaction. All these methods rely on features included by default in browsers, such as JavaScript, rather than on non-default plugins.bash

The term Comet is not an acronym, but was coined by Alex Russell in his 2006 blog post Comet: Low Latency Data for the Browser.服务器

Long-Polling

阻塞模型:客户端发送一个超时时间很长的 Request,服务器 hold 住这个链接,在有新数据到达时返回Response,相比频繁轮询,占用的网络带宽少了。websocket

上述的 问题 在于对于网络带宽的占用及服务器的资源的开销。

轮询的效率低,很是浪费资源(由于必须不停链接,或者 HTTP 链接始终打开) 长轮询须要服务器一直 hold 住连接直到有数据返回,实际上是服务端的一种 hack 方案。

因而,WebSocket 就这样出现来解决上述问题的。

WebSocket 出场

WebSocket 协议在2008年诞生,2011年成为国际标准。全部浏览器都已经支持了。能够在这里查看各个浏览器的支持状况。

WebSocket 是一种在单个 TCP 链接上进行 全双工 通讯的协议。

其余特色包括:

  • 创建在 TCP 协议之上,服务器端的实现比较容易。
  • 与 HTTP 协议有着良好的兼容性。默认端口也是80和443,而且握手阶段采用 HTTP 协议,所以握手时不容易屏蔽,能经过各类 HTTP 代理服务器。
  • 数据格式比较轻量,性能开销小,通讯高效。
  • 能够发送文本,也能够发送二进制数据。
  • 没有同源限制,客户端能够与任意服务器通讯(但一般处于安全性的考虑仍是会带上 origin 头)。
  • 协议标识符是ws(若是加密,则为wss),服务器网址就是 URL。
ws://example-host.com:80/path

// WebSocket + TLS
wss://example-host.com:443/path
复制代码

Events

  • open
  • message
  • error
  • ping/pong
  • close

Methods

  • send
  • text
  • binary
  • close

WebSocket Close Code

协议

WebSocket Http Headers

The WebSocket connection must be an HTTP/1.1 GET request, and include the following headers:

Host

Upgrade: websocket

Connection: Upgrade

Sec-WebSocket-Key

Sec-WebSocket-Version

If any of these are not included in the HTTP headers, the server should respond with an HTTP error code 400 Bad Request.

GET ws://localhost:8181/ HTTP/1.1
Origin: http://localhost:8181
Host: localhost:8181
Sec-WebSocket-Key: zy6Dy9mSAIM7GJZNf9rI1A==
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Version: 13
复制代码

Upon receiving a valid upgrade request with all required fields, the server will decide on the accepted protocol, and any extensions, and send back an HTTP response with status code 101 along with the Sec-WebSocket-Accept handshake acknowledgment.

HTTP/1.1 101 Switching Protocols
Connection: Upgrade
Sec-WebSocket-Accept: EDJa7WCAQQzMCYNJM42Syuo9SqQ=
Upgrade: websocket
WebSocket Frame
复制代码

更多详情请参阅 RFC 6445

参考资料

RFC 6445

《WebSocket: Lightweight Client-Server Communications》 www.ruanyifeng.com/blog/2017/0… baike.baidu.com/item/WebSoc… www.ibm.com/developerwo…

相关文章
相关标签/搜索