WebSocket

2018/08/22 ComputerNetwork 共 2380 字,约 7 分钟

WebSocket

WebSocket是一种基于TCP连接的全双工通信的协议,其工作在应用层,建立连接的时候通过复用http握手通道,完成http协议的切换升级,即切换到WebSocket协议,协议切换成功后,将不再需要客户端发起请求,服务端就可以直接向客户端发送数据,实现双向通信。 相对于Http协议而言,WebSocket有以下优点:

  • 可以支持双向通信
  • WebSocket协议可以更好的支持二进制,可以直接传送二进制数据。
  • 同时WebSocket协议的头部非常小,服务器发到客户端的数据包的包头,只有2~10个字节(取决于数据包的长度),客户端发送服务端的包头稍微大一点,因为其要进行掩码加密,所以还要加上4个字节的掩码。总得来说,头部不超过14个字节。
  • 支持扩展,用户可以扩展协议实现自己的子协议。

WebSocket 建立连接

握手过程

  1. 浏览器、服务器建立TCP连接,三次握手。这是通信的基础,传输控制层,若失败后续都不执行。
  2. TCP连接成功后,浏览器通过HTTP协议向服务器传送WebSocket支持的版本号等信息。(开始前的HTTP握手)
  3. 服务器收到客户端的握手请求后,同样采用HTTP协议回馈数据。http header特殊数据
    1. Connection: Upgrade 表示要升级协议
    2. Upgrade: websocket 表示要升级到websocket协议
    3. Sec-WebSocket-version 表示websocket的版本。
    4. Sec-WebSocket-Key 浏览器生成的一个字符串,服务器端需要取出该字符串,后通过SHA1算法计算出摘要,并转成base64字符串,然后作为Sec-WebSocket-Accept的值放到响应头部返回给客户端,否则会连接失败。关键就是要监听upgrade事件,然后根据Sec-WebSocket-Key生成对应Sec-WebSocket-Accept的key值,然后返回给客户端
  4. 当收到了连接成功的消息后,通过TCP通道进行传输通信。

深入探究

参考

WebSocket 复用了 HTTP 的握手通道。具体指的是,客户端通过 HTTP 请求与 WebSocket 服务端协商升级协议。

协议升级完成后,后续的数据交换则遵照 WebSocket 的协议。

建立链接时需要密钥验证,公开算法,可破解伪造,只是为了避免误操作。

数据帧交互: opcode有Ping,Pong, 二进制交换,断开连接等。

有分片逻辑,最后一帧的FIN为1

客户端到服务端请求需要进行掩码转换,数据不同意伪造。

掩码例子

客户端流程

// 初始化一个 WebSocket 对象
var ws = new WebSocket("ws://localhost:9998/echo");

// 建立 web socket 连接成功触发事件
ws.onopen = function () {
  // 使用 send() 方法发送数据
  ws.send("发送数据");
  alert("数据发送中...");
};

// 接收服务端数据时触发事件
ws.onmessage = function (evt) {
  var received_msg = evt.data;
  alert("数据已接收...");
};

// 断开 web socket 连接成功触发事件
ws.onclose = function () {
  alert("连接已关闭...");
};

HTTP 长连接

HTTP 协议是一种无状态的、无连接的、单向的应用层协议。它采用了请求/响应模型。通信请求只能由客户端发起,服务端对请求做出应答处理。

这种通信模型有一个弊端:HTTP 协议无法实现服务器主动向客户端发起消息。

这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦。大多数 Web 应用程序将通过频繁的异步JavaScript和XML(AJAX)请求实现长轮询。轮询的效率低,非常浪费资源(因为必须不停连接,或者 HTTP 连接始终打开)。

一些“服务器推”技术。

  1. 轮询 客户端以一定的时间间隔发送Ajax请求,优点实现起来比较简单、省事,不过缺点也很明显,请求有很大一部分是无用的,而且需要频繁建立和释放TCP连接,很消耗带宽和服务器资源。

  2. 长轮询 与普通轮询不同的地方在于,服务端接收到请求后会保持住不立即返回响应,等到有消息更新才返回响应并关闭连接,客户端处理完响应再重新发起请求。较之普通轮询没有无用的请求,但服务器保持连接也是有消耗的,如果服务端数据变化频繁的话和普通轮询并无两样。

  3. 长连接 在页面中嵌入一个隐藏的iframe,将其src设为一个长连接的请求,这样服务端就能不断向客户端发送数据。优缺点与长轮询相仿。

这些技术都明显存在两个相同的缺点:

  1. 服务器需要很大的开销
  2. 都做不到真正意义上的“主动推送”,服务端只能“被动”地响应,于是就轮到正主出场了。在websocket中,只需要做一个握手动作就可以在客户端和服务器之间建立连接,之后通过数据帧的形式在这个连接上进行通讯,并且,由于连接是双向的,在连接建立之后服务端随时可以主动向客户端发送消息(前提是连接没有断开)。

VS http

相同点

  1. 都是一样基于TCP的,都是可靠性传输协议。
  2. 都是应用层协议。

不同点

  1. WebSocket是双向通信协议,模拟Socket协议,可以双向发送或接受信息。HTTP是单向的。
  2. WebSocket是需要握手进行建立连接的。

联系:WebSocket在建立握手时,数据是通过HTTP传输的。但是建立之后,在真正传输时候是不需要HTTP协议的。

VS Socket

Socket是传输控制层协议,WebSocket是应用层协议。

Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

Search

    Table of Contents