WebSocket是一种基于TCP的全双工应用层协议(RFC 6455),通过HTTP握手升级建立持久连接,浏览器原生支持new WebSocket(),实现低开销双向实时通信。

WebSocks 不是标准协议或技术术语,它大概率是拼写错误或混淆词——你真正想问的,是 WebSocket 和 Socket 的区别。
WebSocket 是什么?为什么浏览器能直接用?
WebSocket 是一个应用层协议(RFC 6455),专为 Web 场景设计:
- 它依赖 HTTP 协议完成初始握手(发送
Upgrade: websocket请求头),成功后底层切换为纯 TCP 连接; - 握手一旦通过,后续所有通信都走轻量帧(frame),无 HTTP 头开销;
- 浏览器原生支持
WebSocketAPI,比如直接写new WebSocket('wss://example.com')就能连; - 服务器端需显式处理升级请求(如 Node.js 的
http.Server+ws库,或 ASP.NET Core 的WebSocketManager)。
常见错误现象:
- 把
wss://当成加密版ws://就完事了——其实它必须配有效 TLS 证书,否则浏览器直接拒绝连接; - 在 Nginx 反向代理时没透传
Upgrade和Connection头,导致握手失败,报错Unexpected response code: 200或ERR_CONNECTION_REFUSED。
Socket 是什么?为什么不能直接在浏览器里 new Socket()?
Socket 不是协议,而是操作系统提供的底层编程接口,位于应用层和传输层之间:
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- 它封装了 TCP/UDP 的细节,让开发者能读写字节流(
send()/recv())或数据报(sendto()); - 没有内置握手、帧格式、错误重试等逻辑——这些全得你自己定义;
- 浏览器出于安全限制,不暴露原始
SocketAPI(无法直接调用socket(AF_INET, SOCK_STREAM, 0)); - 常见使用场景是服务端进程间通信、游戏服务器、IoT 设备直连等,语言如 C/C++、Go、C# 的
TcpClient、Python 的socket.socket()。
容易踩的坑:
- 误以为
WebSocket是 “基于 Socket 的高级封装” 就能随意替换——其实二者抽象层级不同,不能混用; - 在 Node.js 中用
net.Socket实现自定义协议时,没处理粘包/半包,导致数据解析错乱; - UDP
Socket场景下假设“发出去就一定到”,忽略丢包、乱序问题。
ws://、wss:// 和 HTTP 的关系到底是什么?
ws:// 和 wss:// 是 WebSocket 协议的 URI scheme,但它们不是独立协议栈:
-
ws://对应明文 TCP 连接,握手阶段走 HTTP/1.1; -
wss://强制走 TLS,握手也走 HTTPS,之后才升级为 WebSocket 帧传输; - 两者都复用 HTTP 端口(80/443),方便穿透防火墙和代理;
- 服务器收到 HTTP 请求后,必须检查
Upgrade: websocket头,并返回 101 Switching Protocols 响应,才算真正进入 WebSocket 模式。
关键点:
- 握手失败 ≠ WebSocket 连接失败,而是 HTTP 阶段就卡住了;
- 有些 CDN 或负载均衡器默认不转发
Upgrade请求,需要手动开启 WebSocket 支持; -
fetch()或XMLHttpRequest无法发起 WebSocket 握手——只有WebSocket构造函数可以。
真正的复杂点不在概念,而在于边界模糊处:比如用 WebSocket 传二进制数据时,帧掩码(masking)只在客户端→服务端方向强制启用,服务端→客户端不掩码——这个细节不查 RFC 6455 很容易在自研服务端时出错。

















