webSocket

2019-06-05  本文已影响0人  LoveBugs_King

我们知道http协议是:无状态的,必须由客户端发起请求,服务端才能被动相应。
问题:我们需要做实时聊天,在线炒股等应用,如何让客户端能实时取到服务端最新的数据?
1、轮询,客户端设置一个定时器,以固定间隔给服务端发送ajax请求 来 请求数据。
    但是,频繁的请求会给服务端带来极大压力。
2、Comet,本质也是轮询,在没有相应数据时,服务器会先拖一段时间,等有消息来再响应请求。
    但是,以多线程模式运行的服务器会让大部分线程都出于挂起状态,极大浪费服务端资源。另外,一个Http连接在长时间没有数据传输的情况下,链路上任何一个网关都可能关闭这个连接,而网关是我们不可控的,这就要求Comet连接定期发一些ping数据表示“连接正常”。
结论:两种方法都治标不治本。

webSocket协议出现了

它是利用http协议来建立连接,对http协议进行了改造。
来看一个webSocket请求的格式:

GET: ws://localhost:3000/ws/chat   HTTP/1.1
Host: localhost
Upgrade: websocket
connect: Upgrade
Origin: http://localhost:3000
Sec-WebSocket-Key: client-random-string
Sec-WebSocket-Version: 13

该请求和普通HTTP请求有哪些不同:

  1. GET请求的地址不是类似/path/,而是以ws://开头。
  2. 请求头Upgrade: websocketConnection: Upgrade表示这个连接将要被转换为WebSocket连接。
  3. Sec-WebSocket-Key是用于标识这个连接,并非用于加密数据。
  4. Sec-WebSocket-Version指定了WebSocket的协议版本。

随后,服务器如果接受该请求,就会返回如下反应:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: server-random-string

该响应代码101表示本次连接的HTTP协议即将被更改,更改后的协议就是Upgrade: websocket指定的WebSocket协议。

版本号和子协议规定了双方能理解的数据格式,以及是否支持压缩等等。如果仅使用WebSocket的API,就不需要关心这些。

现在,一个WebSocket连接就建立成功,浏览器和服务器就可以随时主动发送消息给对方。消息有两种,一种是文本,一种是二进制数据。通常,我们可以发送JSON格式的文本,这样,在浏览器处理起来就十分容易。

为什么WebSocket连接可以实现全双工通信而HTTP连接不行呢?实际上HTTP协议是建立在TCP协议之上的,TCP协议本身就实现了全双工通信,但是HTTP协议的请求-应答机制限制了全双工通信。WebSocket连接建立以后,其实只是简单规定了一下:接下来,咱们通信就不使用HTTP协议了,直接互相发数据吧。

安全的WebSocket连接机制和HTTPS类似。首先,浏览器用wss://xxx创建WebSocket连接时,会先通过HTTPS创建安全的连接,然后,该HTTPS连接升级为WebSocket连接,底层通信走的仍然是安全的SSL/TLS协议。

浏览器兼容

Chrome
Firefox
IE >=10
Sarafi >=6
Android >=4.4
IOS >= 8

服务器

由于Webpack是一个协议,服务器具体怎么实现,取决于所用编程语言和框架本身。Node.js本身支持的协议包括TCP和HTTP协议,要支持WebSocket协议,需要对Node.js提供的HTTPServer做额外的开发。已经有若干基于Node.js的稳定可靠的WebSocket实现,我们直接用npm安装即可。

上一篇下一篇

猜你喜欢

热点阅读