1. 概述

Websocket 是一种网络传输协议,可以在 TCP 连接上进行全双工通信,位于 OSI 的应用层,协议版本要求 13 以上。
Websocket 是从 Ajax、Comet(长轮询)逐步衍进的技术,解决 C/S 之间的数据交互、数据互推(全双工)问题,浏览器支持方面目前基本都已经支持,而且在物联网方面也有应用;
Websocket 涵盖了传输+协议两个部分,传输指的是 WS 可以在应用层数据封装(组装成协议 MQTT、AMPQ、SOAP 等)传输数据,实际上还是基于 TCP 上,因此是握手过程是是在 TCP 三次握手后,再基于Connection: Upgrade
、Upgrade: websocket
升级到 websocket 协议,具体内容可以看阅读文档.
针对数据加密方面,ws
是基于 80 端口进行数据传输,wss
是基于443
端口进行数据传输(tls 保障数据传输安全)
实例参考 (tips:通过 chrome webdevelop 工具查看)
2. 握手过程
2.1. 客户端请求
涉及Connetion
、Upgrade
头字段,告知服务端采用 websocket 进行数据通信,并基于Sec-WebSocket-Key
指定客户标识,基于Sec-WebSocket-Version
告知版本为 13
|
|
2.2. 服务器回应
|
|
涉及101
协议选择响应,告知客户端服务端将升级至 websocket,并告知客户端接受的Sec-WebSocket-Accept
,改值是通过客户端发送过来的Sec-WebSocket-Key
加上一个特殊字符串258EAFA5-E914-47DA-95CA-C5AB0DC85B11
,然后计算 SHA-1 摘要,之后进行 BASE-64 编码。
js 生成的代码为:
|
|
3. Nginx 作为 WS 代理
WebSocket 协议与 HTTP 协议不同,但是 WebSocket 握手与 HTTP 兼容,使用 HTTP 升级工具将连接从 HTTP 升级到 WebSocket。这使 WebSocket 应用程序可以更轻松地适合现有基础架构。例如,WebSocket 应用程序可以使用标准的 HTTP 端口 80 和 443,从而允许使用现有的防火墙规则。
WebSocket 应用程序使客户端和服务器之间的长期连接保持打开状态,从而促进了实时应用程序的开发。
用于将连接从 HTTP 升级到 WebSocket 的 HTTP 升级机制使用Upgrade
和Connection
标头。
反向代理服务器在支持 WebSocket 方面面临一些挑战:
- WebSocket 是逐跳协议(
hop‑by‑hop protocol
),因此,当代理服务器截获来自客户端的升级请求时,它需要将其自身的升级请求(包括适当的标头)发送到后端服务器。 - 由于 WebSocket 连接的寿命长,而不是 HTTP 使用的典型的短连接,因此反向代理需要允许这些连接保持打开状态,而不能因为它们是空闲就关闭。
3.1. 代理配置
NGINX 侦听端口 8020,并将请求代理到后端 WebSocket 服务器,proxy_set_header
指令使 NGINX 妥善处理 WebSocket 协议。
|
|
3.2. node 配置一个 ws 服务
|
|
3.3. 启动另一个终端作为 ws 客户端进行 ws 调试
注意将/usr/local/node/bin/
,加入到PATH
目录,这样可以直接执行wscat
命令:
|
|
3.4. 利用 wscat 调试
可以发现,WS 协议经过一次 HTTP 协议升级后,完成了 WS 握手过程,就开始进行数据收发了,内部过程即客户端 wscat 通过Upgrade: websocket
和Connection: Upgrade
,外加版本和 Key 信息发送,服务端响应了HTTP/1.1 101 Switching Protocols
协议切换到websocket
响应。
另外,注意到 ws 后续的收发过程中,是没有 HTTP 协议的相关头信息的,即 ws 等同于应用层的传输协议,可以自定义相关的子协议了,因此其数据传输的效率相比 HTTP 协议的轮询方式要高出很多!

3.5. 利用 chrome 调试工具调试
打开 Chrome 的 Console 控制台,执行下述 JS 脚本,注意需要同源!
|
|
4. 问题讨论
- 并发连接:大多数体面的 WebSocket 服务器可以支持数千个并发连接,但一旦 WebSocket 服务器进程处理了实际数据的接收,处理和响应消息所需的工作量是多少?
- 应用集成:在各种潜在的问题,例如与数据库之间的读取和写入,与游戏服务器的集成,每个客户端的资源分配和管理等等。
- 负载均衡:一台机器无法处理工作负载时,您需要开始添加其他服务器,这意味着现在您需要开始考虑负载平衡
- 数据同步:连接到不同服务器的客户端之间的消息同步
相关问题:服务器的并发连接支持问题,C10K、10M 连接支持(IO 多路复用相关),同时还需要保障业务处理过程中的效率问题
5. 阅读内容
5.1. ably 服务商的文档
文档较为详细讲解了 websocket 的基本知识,下面还有几篇附带的链接也可以读一下!
https://www.ably.io/concepts/websockets
5.2. ably ws 聊天示例,可以直接通过浏览器查看 ws 的连接创建过程
https://www.ably.io/design-patterns/read-receipts
5.3. 其他参考
- websockets wiki: https://zh.wikipedia.org/wiki/WebSocket
- nginx blog: https://www.nginx.com/blog/websocket-nginx/