
WebSocket 是一种网络通信协议,它在单个 TCP 连接上提供全双工 的通信信道,意味着服务器和客户端可以同时向对方发送消息。
1. 为什么需要 WebSocket?
在 WebSocket 出现之前,要实现实时数据更新(如聊天室、实时游戏、股票行情),主要依赖以下技术,但它们都有明显的缺点:
轮询:客户端每隔一段时间(比如1秒)就向服务器发送一个HTTP请求问:"有新数据吗?" 无论服务器有没有新数据,都会返回响应。
- 缺点:浪费带宽和服务器资源,延迟高(最坏情况下的延迟等于轮询间隔)。
长轮询:客户端发起一个HTTP请求,服务器会一直保持这个连接打开,直到有数据可发送。客户端收到响应后立即发起新的请求。
- 缺点:比轮询好一些,但每次请求/响应仍然包含完整的HTTP头,开销不小。实现复杂。
WebSocket 的出现就是为了解决这些问题,它提供了真正的、持久的、低开销的双向通信。
2. WebSocket 的核心特点
全双工通信:客户端和服务器是平等的,都可以随时主动向对方发送消息。
单一的TCP连接:整个通信生命周期只使用一个连接,避免了HTTP的重复握手和断开开销。
低延迟:一旦连接建立,消息可以几乎瞬时地传递,没有HTTP那样的请求-响应周期延迟。
低开销:在初始握手之后,数据传输时的协议头非常小(通常只有2-10字节),远小于HTTP头。
3. WebSocket 连接的生命周期(握手过程)
WebSocket 连接不是凭空建立的,它始于一个特殊的HTTP请求,叫做"握手"。
-
HTTP 握手请求 :
客户端发送一个升级请求,关键头信息如下:
http
GET /chat HTTP/1.1 Host: server.example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== // 一个随机生成的密钥 Sec-WebSocket-Version: 13 // WebSocket 协议版本Upgrade: websocket和Connection: Upgrade告诉服务器,客户端希望将连接升级为 WebSocket 协议。
-
HTTP 握手响应 :
如果服务器支持 WebSocket,它会返回一个响应来完成握手:
http
HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= // 基于客户端密钥计算得出的-
状态码
101 Switching Protocols表示协议切换成功。 -
Sec-WebSocket-Accept是服务器对客户端Sec-WebSocket-Key的验证,确保这是一个合法的 WebSocket 握手。
-
-
连接建立 :
握手成功后,之前的HTTP连接就变成了一个持久的WebSocket连接。此时,通信不再使用HTTP协议,而是使用WebSocket数据帧协议。双方可以开始自由地发送数据。
-
数据传输 :
数据被包装在"帧"中进行传输。帧的设计非常轻量,可以传输文本数据,也可以传输二进制数据(如图片、音频)。
-
连接关闭 :
任何一方(客户端或服务器)都可以发送一个关闭帧来优雅地终止连接。
4. WebSocket 的 API(在浏览器中的使用)
现代浏览器都提供了 WebSocket 对象。
javascript
// 1. 创建 WebSocket 连接,连接到服务器 const socket = new WebSocket('wss://echo.websocket.org'); // ‘wss’ 表示加密的 WebSocket,类似于 HTTPS // 2. 监听连接打开事件 socket.onopen = function(event) { console.log('连接已建立'); // 连接成功后,发送一条消息 socket.send('你好,服务器!'); }; // 3. 监听消息事件 socket.onmessage = function(event) { console.log('收到服务器消息: ', event.data); }; // 4. 监听错误事件 socket.onerror = function(error) { console.error('WebSocket 错误: ', error); }; // 5. 监听连接关闭事件 socket.onclose = function(event) { console.log('连接已关闭', event); }; // 发送消息的函数 function sendMessage(message) { if (socket.readyState === WebSocket.OPEN) { socket.send(message); } } // 关闭连接 function closeConnection() { socket.close(); }
5. 适用场景
实时聊天应用(微信、钉钉、Discord)
多人在线游戏
实时数据仪表盘(股票行情、系统监控、体育赛事比分)
协同编辑工具(如 Google Docs)
在线教育(白板、老师学生互动)
6. 不适用场景
- 一次性获取数据(如加载一篇文章、提交一个表单)。对于这种简单的请求-响应模式,使用 RESTful API 更简单、更合适。
7. 与 HTTP/2 和 Server-Sent Events 的比较
HTTP/2 : 主要优化了HTTP/1.1的性能(多路复用、头部压缩等),但它本质上仍是请求-响应模型。服务器不能主动推送,要实现"推送",需要依赖客户端发起请求(如Server Push,但用法复杂且有限)。
Server-Sent Events : 允许服务器主动向客户端推送数据,但它是单向的(只能服务器->客户端)。对于只需要服务器推送而客户端不需要发送复杂消息的场景,SSE是一个更轻量的选择。
下面这段是一个博主的文章的,我觉得说的挺完整的,有些个人理解不深刻的点也说到了,关于长轮询和轮询的这点其实我还没有彻底理解(项目实际经验的理解),但是做个备份,查找方便是可以的,以后我更深刻的理解,文章再附上。
关于这篇完整文,可以去看原文:
一、什么是 WebSocket
WebSocket 是 HTML5 开始提供的一种,建立在单个 TCP 连接上的全双工的网络通信协议。WebSocket 协议在2008年诞生,2011年成为国际标准。现在最新版本浏览器都已经支持了。
它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。
熟悉计算机网络协议的人都知道:HTTP 协议是一种无状态的、无连接的、单向的应用层协议。它采用了请求/响应模型。这种通信模型有一个弊端:HTTP 协议无法实现服务器主动向客户端发起消息。
二、WebSocket 应用场景
即时聊天通信
在线协同编辑/编辑
实时数据流的拉取与推送
实时地图位置
三、WebSocket 协议原理及与 HTTP 的关系
WebSocket 协议(以下简称,ws协议),与http协议一样,需要通过已建立的TCP连接来传输数据。具体实现上是先通过http协议建立通道,然后在此基础上用真正ws协议进行通信,所以ws协议和http协议是有一定的交叉关系的。
3.1 ws和Http区别:
相对于 HTTP 这种非持久的协议来说, ws协议是一个持久化协议。
举个例子:
HTTP 的生命周期通过 Request 来界定,也就是一个 Request 一个 Response ,那么在 HTTP1.0 中,这次 HTTP 请求就结束了。
在 HTTP1.1 中进行了改进,加了一个 keep-alive。也就是说,在一个 HTTP 连接中,可以发送多个 Request,接收多个 Response。但是,时刻扣住一个点:在 HTTP 中永远是一个 Request 对应一个 Response。而且这个 Response 也是被动的,服务端不能主动发起。
3.2 ws和Http联系:
WebSocket 是基于 HTTP 协议的,或者说借用了 HTTP 协议来完成一部分握手。
四、WebSocket 通信过程
首先我们来看个典型的 WebSocket 握手
4.1 客户端发送ws握手的请求信息如下:
熟悉 HTTP 的道友可能发现了,这段类似 HTTP 协议的握手请求中,多了Upgrade:websocket 和 Sec-WebSocket-Version、Sec-WebSocket-Key等。
这些就是ws协议的核心部分,告诉服务器我发起的请求要用ws协议。
其中:
Upgrade:websocket:表示我要用ws协议通信
Sec-WebSocket-Version:是ws版本号。
Sec-WebSocket-Key 是一个 Base64 encode 的值,由浏览器随机生成。
4.2 服务器响应报文示例:
我们先来了解一下,服务器在收到ws握手报文要干什么吧:

4.3 小结:
客户端发起http请求,经过3次握手后,建立起TCP连接(注意:ws在发送握手前,Tcp的连接已经建立,也就是说Tcp的三次握手已经成功)。
ws握手报文里存放ws支持的版本号等信息,如:Upgrade、Connection、WebSocket-Version等;
然后,服务器收到客户端的握手请求后,同样采用HTTP协议回馈数据;
最后,客户端收到连接成功的消息后,开始借助于TCP传输信道进行全双工通信。
五、Websocket的优缺点
优点:
WebSocket协议一旦建议后,互相沟通所消耗的请求头是很小的
服务器可以向客户端推送消息了
缺点:
少部分浏览器不支持,浏览器支持的程度与方式有区别(IE10)
六、总结
WebSocket 是为了在 web 应用上进行双通道通信而产生的协议,相比于轮询HTTP请求的方式,WebSocket 有节省服务器资源,效率高等优点。
WebSocket 中的掩码是为了防止早期版本中存在中间缓存污染攻击等问题而设置的,客户端向服务端发送数据需要掩码,服务端向客户端发送数据不需要掩码。
WebSocket 中 Sec-WebSocket-Key 的生成算法是拼接服务端和客户端生成的字符串,进行SHA1哈希算法,再用base64编码。WebSocket 协议握手是依靠 HTTP 协议的,依靠于 HTTP 响应101进行协议升级转换。
