WebSocket协议详解


WebSocket协议是一种基于TCP的、全双工的、持久的网络通信协议,旨在在单个 TCP 连接上提供客户端(通常是 Web 浏览器)和服务器之间的双向、低延迟、实时通信通道。它解决了传统 HTTP 轮询或长轮询在实现实时应用(如聊天、在线游戏)时,效率低下和延迟高的问题。

一、轮询与长轮询

轮询和长轮询是早期实现“伪实时”通信的技术,用于在 HTTP 协议(本身是请求-响应模型)上模拟服务器向客户端的推送。它们本质上是客户端主动、反复询问服务器是否有新数据。

1.轮询

原理:客户端定期(例如每隔 1 秒、5 秒、30 秒)向服务器发送一个标准的 HTTP 请求,询问是否有新数据。无论服务器是否有新数据,都会立即返回一个响应。

  • 优点:
    • 实现非常简单。
    • 概念清晰易懂。
  • 缺点:
    • 高延迟: 新数据产生后,客户端最多需要等待一个完整的轮询间隔才能收到(平均延迟 = 间隔时间 / 2)。实时性差。
    • 高网络开销: 大量请求是无效的(服务器无数据时也要响应),浪费带宽和服务器资源(处理请求、建立/关闭连接)。
    • 高服务器负载: 即使没有更新,服务器也要不断处理大量“空查询”请求。
    • 电池消耗 (移动端): 频繁的网络请求和唤醒设备会显著消耗电池。

2.长轮询

原理:客户端发起一个请求,但服务器不会立即响应。服务器将这个请求“挂起”,直到:(1) 有新数据可用,或者;(2)达到一个预设的超时时间。此时服务器才返回响应。客户端收到响应后(无论是否有新数据),立即发起下一个长轮询请求。

  • 优点 (相比基础轮询):
    • 显著降低延迟: 一旦服务器有新数据,就能立即推送给等待中的客户端,无需等待下一个轮询间隔。平均延迟更低,接近实时。
    • 减少无效请求: 服务器只在有数据或超时时才响应,减少了大量“空转”的请求和响应。
    • 降低网络开销和服务器负载 (相比基础轮询): 无效请求/响应的数量大幅减少。
  • 缺点:
    • 实现更复杂: 服务器需要维护挂起的请求(连接),涉及连接管理和状态跟踪。对服务器框架有要求(需要支持异步、非阻塞 I/O 或类似机制)。
    • 连接管理开销: 每次长轮询结束(无论是否有数据),都需要关闭当前 HTTP 连接,客户端立即建立一个新的连接。频繁的连接建立/关闭仍有开销(TCP 握手、TLS 握手)。
    • 超时问题: 需要合理设置服务器端的超时时间。太短会导致过多“超时空响应”和频繁重建连接;太长可能导致客户端连接因代理、防火墙或浏览器限制而意外中断。
    • 服务器资源占用: 挂起的连接仍然消耗服务器资源(内存、文件描述符)。高并发时,大量挂起的连接可能导致服务器资源耗尽。
    • 消息顺序保证: 在客户端处理上一个响应并发出下一个请求的短暂间隙,如果服务器有新数据到达,可能会丢失或延迟,需要额外机制保证。
    • 不是真正的推送: 仍然是客户端发起的请求,服务器只是“延迟”了响应。

二、WebSocket 协议特点

  • 双向通信:客户端和服务端可以随时独立地向对方发送数据,无需先请求。
  • 低延迟:建立连接后,数据帧直接在 TCP 层传输,避免了 HTTP 请求/响应的开销。
  • 低开销:数据帧头非常精简(最小仅 2 字节),显著减少了带宽消耗。
  • 基于 TCP:提供可靠、有序的字节流传输。
  • 与 HTTP 协同工作:握手阶段兼容 HTTP,便于通过防火墙和代理,并共享默认端口(ws:80、wss:443)。
  • 支持扩展和子协议:允许定义扩展(如压缩)和子协议(如STOMP、WAMP)以满足特定应用需求。

三、工作流程

1.握手

  • 客户端发起一个特殊的 HTTP Upgrade 请求。
GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
  • 请求头包含:
    • Connection:Upgrade
    • Upgrade:websocket
    • Sec-WebSocket-Key:一个随机的 Base64编码值(由浏览器生成)。
    • Sec-WebSocket-Version:协议版本(通常是13)。
    • Sec-WebSocket-Protocol:(可选)客户端希望使用的子协议列表。
    • Origin:(浏览器通常发送)用于同源策略检查。
  • 服务器响应一个 HTTP 101 Switching Protocols 响应。
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
  • 响应头包含:
    • Connection:Upgrade
    • Upgrade:websocket
    • Sec-WebSocket-Accept:一个基于客户端发送的 Sec-WebSocket-Key 计算出的值(证明服务器理解 WebSocket 协议)。
    • Sec-WebSocket-Protocol:(可选)服务器从客户端列表中选择的一个子协议。

2.数据传输

  • 握手成功后,TCP 连接保持打开状态,但通信协议从 HTTP 升级为 WebSocket。
  • 数据以消息的形式交换。一条消息可以由一个或多个帧组成。
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len |    Extended payload length    |
|I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
|N|V|V|V|       |S|             |   (if payload len==126/127)   |
| |1|2|3|       |K|             |                               |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
|     Extended payload length continued, if payload len == 127  |
+ - - - - - - - - - - - - - - - +-------------------------------+
|                               |Masking-key, if MASK set to 1  |
+-------------------------------+-------------------------------+
| Masking-key (continued)       |          Payload Data         |
+-------------------------------- - - - - - - - - - - - - - - - +
:                     Payload Data continued ...                :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
|                     Payload Data continued ...                |
+---------------------------------------------------------------+
  • 帧是传输的基本单位,具有特定的二进制格式:
    • FIN(1 bit):指示是否是消息的最后一帧。
    • RSV1,RSV2,RSV3(各 1 bit):保留位,用于扩展。
    • Opcode(4 bits):定义帧的类型(文本、二进制、连接关闭、ping、pong等)。
    • Mask(1 bit):指示 Payload Data 是否被掩码(客户端到服务器的帧必须掩码,服务器到客户端的帧不掩码)。
    • Payload Length(7,7+16,7+64 bits):有效载荷数据长度。
    • Masking-Key(0 or 4 bytes):如果 Mask 为 1,则存在 4 字节的掩码秘钥。
    • Payload Data:实际传输的数据(文本或二进制)。如果 Mask 为 1,该数据需与 Masking-Key 进行异或运算以解除掩码。
    • 常见的帧类型(Opcode):
      • 0x0:延续帧
      • 0x1:文本帧-UTF-8 编码
      • 0x2:二进制
      • 0x8:连续关闭帧
      • 0x9:Ping 帧
      • 0xA:Pong 帧

3.连接关闭

  • 任何一端都可以发送一个关闭帧来发起关闭。
  • 关闭帧可以包含一个状态码(如 1000 表示正常关闭)和可选的关闭原因。
  • 收到关闭帧的一端必须发送一个关闭帧作为响应。
  • 发送关闭帧后,该端点不再发送任何数据。
  • 收到对方的关闭帧后,端点认为连接已关闭,并关闭底层的 TCP 连接。
  • Ping/Pong 机制:
    • 服务器或客户端可以发送 Ping 帧。
    • 接收方收到后必须尽快回复一个 Pong 帧(通常携带与 Ping 帧相同的 ApplicationData)。
    • 用途:保持连接活跃、检测连接是否仍然有效(心跳)、测量延迟。

四、URL方案

  • ws://:非加密 WebSocket 连接(对应 HTTP)。
  • wss://:加密 WebSocket 连接(对应 HTTPS)。

五、优点

  • 真正的实时性:服务端可以主动推送数据给客户端,无需等待客户端请求。
  • 高效:极低的协议开销,节省带宽和服务器资源。
  • 减少延迟:避免了 HTTP 请求的往返时间。
  • 复用连接:一个连接处理所有通信。

六、与 HTTP 的关键区别

特性HTTP (Request/Response)WebSocket
通信模式半双工 (客户端发起请求)全双工 (双方可随时发送)
连接状态无状态 (通常每次请求后关闭)持久化连接
数据流单向 (请求 -> 响应)双向 (消息流)
延迟较高 (每次交互需握手/头开销)极低 (连接后直接传输帧)
开销较高 (每次请求携带完整头)极低 (精简帧头)
发起方只能是客户端双方均可主动发起数据
用途文档、资源获取实时交互应用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值