HTML5 WebSocket 入门






4.85/5 (37投票s)
HTML5 WebSocket 入门
什么是 WebSocket?
WebSocket 是一种 Web 技术,可在单个 TCP 连接上提供全双工通信通道。全双工通信是一种允许同时进行双向通信的通信系统。 电话对话是全双工通信的一个很好的例子,在电话对话中,双方可以同时讲话和听到对方讲话。
我们为什么需要 WebSocket?
当前的 Web 依赖于 HTTP 进行通信,而 HTTP 是一种 请求-响应协议。为了实现类似桌面(实时)的体验, 程序员会使用轮询、长轮询和流式传输等技术。
其次,这不是全双工通信。这意味着客户端和服务器不能同时发送和接收消息。
例如
对讲机通信——其中一方必须发送一个 预先指定的命令(如“Over”)来指示传输结束,然后另一方才能开始响应。
WebSocket 有何优势?
WebSocket 是 HTML 5 定义的一部分的新标准,用于 解决当前 Web 的两个主要问题:
- HTTP 的开销 (网络吞吐量)
- 低延迟
WebSocket 使用 IETF 定义的自己的协议与 服务器通信。
WebSocket 还具有一个名为 WebSocket API 的 API,用于打开-关闭与服务器的连接以及发送-接收消息。
通过 WebSocket,我们可以实现客户端和服务器之间全双工的双向通信,其开销远低于上面讨论的基于 HTTP 的方法,并且可以提供更快、更具扩展性的 Web 应用程序。
此外,WebSocket 可以在 TCP 端口 80 上通信。这对于阻止非标准互联网连接的防火墙环境非常有益。
在一项实验中,<a href="http://www.websocket.org/quantum.html">Websocket.org</a> 详细比较了 Ajax 轮询和 WebSocket 的性能。作为该实验的一部分,他们创建了两个网页,其中一个通过 定期 AJAX 轮询与服务器通信,另一个使用 WebSocket。每个 HTTP 请求/响应 头部大约为 871 字节,而 WebSocket 帧中的每个消息仅为 2 字节。
这是关于负载增加时这对网络吞吐量和延迟的影响的比较。
AJAX 轮询
- 用例 A :每秒轮询 1,000 个客户端:网络吞吐量为(871 x 1,000)= 871,000 字节 = 6,968,000 位/秒(6.6 Mbps)
- 用例 B :每秒轮询 10,000 个客户端:网络 吞吐量为(871 x 10,000)= 8,710,000 字节 = 69,680,000 位/秒(66 Mbps)
- 用例 C:每秒轮询 100,000 个客户端:网络吞吐量为(871 x 100,000)= 87,100,000 字节 = 696,800,000 位/秒(665 Mbps)
HTML5 WebSocket
- 用例 A:每秒接收 1 条消息的 1,000 个客户端:网络吞吐量为(2 x 1,000)= 2,000 字节 = 16,000 位/秒(0.015 Mbps)
- 用例 B:每秒接收 1 条消息的 10,000 个客户端:网络吞吐量为(2 x 10,000)= 20,000 字节 = 160,000 位/秒(0.153 Mbps)
- 用例 C:每秒接收 1 条消息的 100,000 个客户端:网络吞吐量为(2 x 100,000)= 200,000 字节 = 1,600,000 位/秒(1.526 Mbps)
轮询与 WebSocket 网络吞吐量比较
轮询与 WebSocket 延迟比较
WebSocket 如何工作?
WebSocket 通信分为两部分:握手和数据传输。
当客户端创建 WebSocket 对象时,客户端和服务器之间会进行握手。客户端首先向服务器发送一个 HTTP GET Upgrade 请求。
客户端和服务器之间的握手如下所示:
这里需要注意的一个重要事项是 “sec-WebSocket-Key” 和 “sec-WebSocket-Accept”。
客户端在头部中将“sec-WebSocket-Key”字符串发送给服务器。服务器会将 GUID 字符串 "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" 附加到“sec-WebSocket-Key”头部字段的值中,并在响应头部字段“sec-WebSocket-Accept”中将此连接字符串的 base64 编码的 SHA-1 哈希值发送给客户端。
握手完成后,客户端和服务器 就可以通过单个 TCP 连接开始发送消息了。
WebSocket API
W3C 在 w3c.org 上有一个 WebSocket API 的工作草案。
客户端-服务器通信
示例客户端实现
$(document).ready(function () {
if ("WebSocket" in window) {
console.log('WebSocket is supported by your browser.');
var serviceUrl = 'ws://:2020/';
var protocol = 'Chat-1.0';
var socket = new WebSocket(serviceUrl, protocol);
socket.onopen = function () {
console.log('Connection Established!');
};
socket.onclose = function () {
console.log('Connection Closed!');
};
socket.onerror = function (error) {
console.log('Error Occured: ' + error);
};
socket.onmessage = function (e) {
if (typeof e.data === "string") {
console.log('String message received: ' + e.data);
}
else if (e.data instanceof ArrayBuffer) {
console.log('ArrayBuffer received: ' + e.data);
}
else if (e.data instanceof Blob) {
console.log('Blob received: ' + e.data);
}
};
socket.send("Hello WebSocket!");
socket.close();
}
});
服务器实现选项
对于各种服务器端技术,有多种 WebSocket 服务器实现选项。下面列出了一些广泛使用的技术的一些流行 WebSocket 服务器实现:
- .NET
- Fleck
- ASP.NET 4.5
- SuperWebSocket
- XSocket.NET
- Java
- jWebSocket
- JettyWebSocket
- Node.js
- Socket.IO
- WebSocket-Node
浏览器支持
图片来源: https://caniuse.cn/websockets