为了让 WebSocket 能够顺利地"穿过"现有的互联网基础设施(尤其是防火墙和代理服务器),同时保持与 HTTP 生态系统的良好兼容**。
下面是详细的解释,说明了为什么要这么设计:
1. 最大的原因:对现有网络基础设施的兼容与穿透
互联网世界充满了各种中间设备,如代理服务器、防火墙、负载均衡器、网关 等。这些设备有一个共同点:它们被设计和配置为理解和处理 HTTP 流量。
-
如果 WebSocket 一上来就用自定义的二进制协议 :
一个非 HTTP 的、陌生的数据流试图连接到服务器的 80 或 443 端口(HTTP/HTTPS 的标准端口),这些中间设备会完全看不懂这个流量。
- 防火墙 :可能会认为这是一种未知的、潜在的恶意协议,直接拒绝或丢弃连接。
- 代理服务器:无法识别该协议,可能无法正确路由,或者直接返回错误。
-
而采用 HTTP 升级请求的方式 :
WebSocket 握手包"伪装"成一个普通的 HTTP GET 请求。这对于中间设备来说:
- 看起来完全合法 :它拥有所有标准的 HTTP 头(
Host,Upgrade,Connection等),中间设备可以正常解析和处理它,并允许其通过。 - 易于路由:代理服务器知道这是发往某个 Web 服务器的 HTTP 请求,会按规则将其转发。
- "骗过"防火墙:因为是从 80/443 端口发起的、格式正确的 HTTP 流量,防火墙通常会放行。
- 看起来完全合法 :它拥有所有标准的 HTTP 头(
这就好比你要进入一个只认工作证的大楼。如果你直接往里冲,保安会拦住你。但如果你先出示一张标准格式的访客申请单(HTTP请求),保安审核后给你换发一张内部通行证(101响应),之后你就可以自由进出了。HTTP请求就是那张"访客申请单"。
2. 安全性:防止跨协议攻击 (Cross-Protocol Attacks)
这种设计建立了一个重要的安全屏障。假设没有这个握手过程,任何客户端都可以随意向任何服务器的 80 端口发送非 HTTP 数据。
-
攻击场景:一个恶意客户端可以尝试与一个 SMTP(邮件)服务器或 SSH 服务器建立 WebSocket 连接。如果服务器恰好在 80 端口监听,它可能会错误地将 WebSocket 的二进制数据流解释为 SMTP 或 SSH 命令,从而导致不可预料的后果(如发送垃圾邮件)。这就是跨协议攻击。
-
HTTP 升级握手如何解决:
- 客户端必须发送一个格式非常具体 的 HTTP 请求(包含
Upgrade: websocket等特定头字段)。 - 服务器只有在明确理解并同意这个升级请求后(返回 101 状态码),才会切换协议。
- 关键的
Sec-WebSocket-Key和Sec-WebSocket-Accept握手验证确保了对方确实是一个理解 WebSocket 协议的端点,而不是一个可能被意外攻击的普通 HTTP 服务器。
- 客户端必须发送一个格式非常具体 的 HTTP 请求(包含
这确保了协议升级是双方明确协商一致的结果,而不是单方面的行为,有效避免了协议误用。
3. 与现有 Web 架构的无缝集成
- 共享端口 :WebSocket 服务可以和 Web(HTTP)服务部署在同一个域名和端口 (如
example.com:443)上。这简化了部署,无需为实时服务开放新的端口,也避免了新的跨域问题。 - 复用安全模型 :WebSocket over TLS(
wss://)复用 HTTPS 的加密通道和证书体系。握手过程在 TLS 加密之后进行,保证了密钥交换的安全。 - 复用身份验证和授权:服务器可以在处理 HTTP 升级请求时,先行检查标准的 HTTP 身份验证信息(如 Cookies、Authorization头)。这意味着你可以直接用你网站现有的用户登录系统来授权 WebSocket 连接,无需额外开发一套认证机制。
4. 明确的协议协商
HTTP 升级机制提供了一个标准化的、双方都能理解的"协商语言"。通过请求和响应头,客户端和服务器可以就一些选项达成一致,例如:
- 子协议(Subprotocol) :客户端可以请求使用
soap或wamp等特定上层协议,服务器可以在响应中确认。 - 扩展(Extensions):如压缩扩展,双方可以协商是否启用。
总结
WebSocket 协议这样设计,是一个极具前瞻性和实用性的工程决策:
| 设计选择 | 解决的问题 | 带来的好处 |
|---|---|---|
| 以标准 HTTP 请求开始 | 穿透防火墙、代理等中间设备 | 极高的连接成功率,易于部署和普及 |
| 使用 101 状态码升级 | 需要明确的、双方同意的协议切换 | 避免跨协议攻击,连接安全可靠 |
| 复用 HTTP 端口和基础设施 | 简化部署和集成 | 与现有 Web 服务无缝结合,共享安全模型和认证 |
它完美地平衡了创新 (提供全新的全双工通信能力)与务实(兼容现有庞大网络生态)之间的矛盾。如果没有这个精巧的"HTTP 外套",WebSocket 可能根本无法像今天这样被广泛支持和应用。