WebSocket — 一种全双工通信协议,在客户端和服务器之间提供持久连接,用于实时数据交换。与传统的HTTP请求不同,该协议建立单一连接并将其用于双向传输,无需重复握手。根据 Mozilla Developer Network (2025) 的数据,在实时应用中,WebSocket 的延迟比HTTP轮询降低了最多50%。
要点
WebSocket — 是一种基于TCP的通信协议,在客户端和服务器之间提供全双工通道。它由IETF于2011年标准化为RFC 6455,并得到所有现代浏览器、移动平台和服务器框架的支持。
与HTTP不同,HTTP中客户端发起请求并接收响应,而WebSocket允许双方在建立连接后随时发送消息。这使其成为需要即时数据传送场景的理想选择:聊天、通知、协作文档编辑。
WebSocket协议使用HTTP端口80或HTTPS端口443进行初始握手,之后切换到自己的协议,头部信息极小——仅2字节,而HTTP需要800+字节。这一特性在大量消息时带来显著的性能优势。
WebSocket连接以HTTP升级请求开始,之后协议切换到二进制帧格式。帧的大小从2字节到2^63字节不等,既可以传输短文本消息,也可以传输大型二进制数据。支持消息分片、从客户端到服务器的数据掩码以及用于保持连接的ping/pong。
建立WebSocket连接的过程包括两个阶段:握手和数据传输。在握手阶段,客户端发送带有Upgrade: websocket头部的HTTP请求,服务器以状态101 Switching Protocols确认协议切换。之后,连接进入全双工传输模式。
WebSocket中的每条消息被分割成帧。帧包含操作码(文本、二进制数据、关闭、ping/pong)、有效载荷长度和来自客户端的数据掩码密钥。帧可以被分片——控制帧(ping/pong)可以在消息片段之间传输,防止长时间传输时连接断开。
const ws = new WebSocket('wss://example.com/chat')
ws.addEventListener('open', () => {
console.log('连接已建立')
ws.send('你好,服务器!')
})
ws.addEventListener('message', (event) => {
console.log('已收到:', event.data)
})
ws.addEventListener('close', () => {
console.log('连接已关闭')
})
在上面的示例中,客户端创建一个WebSocket对象,指定安全的URL wss://。连接打开后,发送一条欢迎消息,message处理程序接收来自服务器的响应。关闭时,触发close处理程序——这对于网络中断时重新连接非常重要。
WebSocket和HTTP之间的主要区别在于交互模型。HTTP按照请求-响应方案工作:客户端发起请求,服务器返回响应,连接关闭。而WebSocket建立一个永久通道,双方可以通过该通道随时发起传输。
对于需要低延迟和持续数据流的应用,WebSocket明显更高效。HTTP长轮询——服务器保持请求打开直到数据出现——会给服务器带来额外负载,并因大量并发连接而增加内存消耗。
| 参数 | WebSocket | HTTP |
|---|---|---|
| 模型 | 全双工 | 请求-响应 |
| 头部 | 2–14字节 | 400–800字节 |
| 持久连接 | 是,一个 | 否,每个请求新建 |
| 延迟 | 低(1–5毫秒) | 高(50–200毫秒) |
| 协议 | ws:// 或 wss:// | http:// 或 https:// |
根据《高性能浏览器网络》(Grigorik, O’Reilly),WebSocket在实时场景中将网络延迟比HTTP长轮询降低40–60%,由于消除了重复握手,服务器负载降低3–5倍。
凭借低延迟和双向通信,WebSocket被广泛应用于各种场景。关键场景包括即时消息交换、游戏状态同步和金融系统中的市场数据传输。
WebSocket已成为聊天应用的事实标准。Slack、Telegram Web和WhatsApp Web等平台使用WebSocket进行即时消息投递。该协议允许通过单一通道发送文本消息和文件,ping/pong机制即使在无活动时也保持连接活跃。
多人在线浏览器和手机游戏需要最小延迟来同步玩家状态。WebSocket实时传输坐标、动作和事件,无需HTTP请求的延迟。Socket.IO和Colyseus等框架抽象了与协议的低级工作,并添加了自动重连和房间功能。
证券终端和交易平台使用WebSocket实时接收报价。几毫秒的延迟可能价值数百万美元,因此金融API——例如Binance WebSocket Streams、Coinbase Pro——正是为市场数据提供WebSocket接口。
在移动开发中,WebSocket通过原生API使用:iOS上的URLSessionWebSocketTask和Android上的OkHttp WebSocket。Flutter有web_socket_channel库,React Native有react-native-websocket。物联网设备使用WebSocket传输遥测数据和接收控制命令,因为该协议比持续的HTTP轮询消耗更少的能量。
让我们看看在Node.js中使用ws库的服务器端示例——这是JavaScript最流行的WebSocket实现。服务器接受连接、处理消息并将其广播给所有连接的客户端。
const WebSocket = require('ws')
const wss = new WebSocket.Server({ port: 8080 })
wss.on('connection', (ws) => {
console.log('新客户端已连接')
ws.on('message', (data) => {
console.log('已收到:', data.toString())
ws.send('服务器已收到您的消息')
})
ws.on('close', () => {
console.log('客户端已断开')
})
})
console.log('WebSocket服务器已在8080端口启动')
服务器在端口8080上创建WebSocket.Server实例并等待连接。每个新客户端被分配一个单独的ws对象,服务器可以通过它单独发送消息。向所有客户端广播消息通过遍历连接数组实现。当客户端数量较多(超过1000)时,建议使用支持集群的库,如Socket.IO,它通过Redis添加了扩展性和自动重连。
wss.clients.forEach((client) => {
if (client.readyState === WebSocket.OPEN) {
client.send('发送给所有参与者的消息')
}
})
发送前检查readyState是必需的:如果客户端已断开连接,send调用将抛出错误。WebSocket.OPEN标志确保连接活跃,消息将被送达。
对于移动iOS应用,WebSocket通过URLSessionWebSocketTask实现,自iOS 13起可用。会话使用wss://协议的URL创建任务,然后调用send和receive方法。消息接收可以通过持续的receive递归来组织,在处理前一条消息后等待下一条消息,确保无需重连即可持续接收数据。对于Android,使用OkHttp WebSocket,它提供类似的接口,带有onOpen、onMessage、onClosing和onClosed回调,以及在连接断开时自动重连。
在移动应用中使用WebSocket时,必须考虑生命周期管理:当应用进入后台时,系统可能断开连接。在iOS上,需要通过sceneDidBecomeActive委托在返回前台时重建连接。在Android上,应使用生命周期感知组件或Service来保持连接。此外,建议在重连时实现指数退避——将尝试间隔从1秒增加到30秒——以避免在临时网络问题时对服务器造成过大负载。
常见问题
WebSocket建立持久全双工连接,双方可随时发送数据。HTTP按照请求-响应方案工作,每次交换需要新连接和完整头部。WebSocket使用单一TCP通道和仅2–14字节的头部,大大降低了延迟。
WebSocket使用端口80进行不安全连接(ws://),端口443进行安全连接(wss://)。这使得它可以在无需额外配置的情况下通过大多数代理服务器和企业防火墙。端口443由于TLS加密而被推荐用于生产环境。
是的,WebSocket在所有移动平台上都受支持。在iOS上,原生类URLSessionWebSocketTask自iOS 13起可用。在Android上——OkHttp WebSocket类和标准java.net.WebSocket。React Native有react-native-websocket库。
WebSocket Secure — 基于TLS的安全协议版本。所有数据都像HTTPS一样加密。WSS对于生产应用是必需的,特别是在通过WebSocket传输认证令牌或个人数据时。
主要替代方案:HTTP长轮询(服务器保持请求打开)、服务器推送事件(服务器单向流)和WebRTC数据通道(点对点通信)。服务器推送事件实现更简单,但不支持从客户端向服务器发送数据。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。