WebSocket基础:协议原理、与HTTP的区别、心跳机制
做量化交易,实时性就是生命线。
我记得刚入行那会儿,用的还是轮询方式拿行情数据。每秒请求一次,结果服务器那边数据更新了,我这还没拿到。等拿到了,价格已经变了。那感觉,就像在抢跑线上永远慢半拍。后来换了WebSocket,才真正体会到什么叫「实时」。今天我们就来聊聊这个让量化交易脱胎换骨的技术。
WebSocket协议原理
WebSocket,说白了就是一个全双工通信协议。它建立在TCP之上,让客户端和服务器可以随时互相发消息,不用像HTTP那样一问一答。
它的工作流程分两步:
- 握手阶段:客户端发一个特殊的HTTP请求,要求升级协议
- 数据传输阶段:握手成功后,双方直接通过WebSocket帧交换数据
握手请求长这样:
GET /ws HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
服务器收到后,会计算一个响应密钥返回:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
嗯,这里要注意。握手成功后,连接就从HTTP协议切换到了WebSocket协议。之后的数据传输,不再需要HTTP头,开销极小。
核心要点:WebSocket的数据帧非常轻量。一个帧最小只有2字节,而HTTP请求光头部就几百字节。在行情数据高频推送的场景下,这个差距就是天壤之别。
与HTTP的区别
我经常跟团队新人说:HTTP是打电话,你拨一次号,对方接一次,挂断。WebSocket是对讲机,频道一开,随时说话。
具体区别,我整理了一张表:
| 对比维度 | HTTP | WebSocket |
|---|---|---|
| 通信模式 | 请求-响应(半双工) | 全双工 |
| 连接方式 | 每次请求新建连接 | 一次握手,长连接 |
| 头部开销 | 大(几百字节) | 小(2-14字节) |
| 实时性 | 差(需轮询) | 强(服务端主动推送) |
| 适用场景 | 网页、API接口 | 实时行情、即时通讯 |
你想想看,如果做高频交易,用HTTP轮询拿行情,每次请求都要经历三次握手、四次挥手。等你拿到数据,黄花菜都凉了。WebSocket一次握手后,数据就像流水一样源源不断。
个人经验:我在对接某交易所行情时,一开始用了HTTP轮询,延迟在200ms左右。换成WebSocket后,延迟降到了10ms以内。这个差距,在量化交易里就是赚钱和亏钱的区别。
心跳机制
长连接最怕什么?断线了还不知道。
WebSocket本身没有强制的心跳机制,但实际项目中,我们都会自己实现。为什么?因为网络环境复杂,防火墙、NAT设备可能会把空闲连接断开。我曾经遇到过,连接看起来好好的,但数据已经收不到了。排查了半天,才发现是中间设备把连接掐了。
心跳机制的原理很简单:
- 客户端定时发送一个心跳包(通常是ping帧)
- 服务器收到后回复pong帧
- 如果超过一定时间没收到回复,就判定连接断开
代码实现大概这样:
// 客户端心跳实现
const ws = new WebSocket('wss://api.example.com/ws');
// 每30秒发送一次心跳
const heartbeatInterval = setInterval(() => {
if (ws.readyState === WebSocket.OPEN) {
ws.ping(); // 发送ping帧
}
}, 30000);
// 监听pong响应
ws.on('pong', () => {
console.log('心跳正常');
});
// 超时检测(60秒无响应则重连)
let heartbeatTimeout;
ws.on('ping', () => {
clearTimeout(heartbeatTimeout);
heartbeatTimeout = setTimeout(() => {
ws.close();
reconnect(); // 重连逻辑
}, 60000);
});
避坑指南:我曾经在某个项目中,心跳间隔设得太短(5秒一次),结果服务器以为是攻击,直接把连接封了。建议心跳间隔设在20-30秒,超时时间设在60秒左右。另外,心跳包不要携带业务数据,保持轻量。
知识体系总览
下面这张图,把WebSocket的核心脉络梳理了一遍:
说白了,WebSocket就是为实时而生。协议原理让你知道它怎么工作,与HTTP的区别让你知道为什么选它,心跳机制让你知道怎么让它稳定运行。这三块吃透了,实时行情这块地基就算打牢了。
我的建议:刚开始接触WebSocket时,别急着写代码。先抓包看看握手过程,再模拟一下心跳超时场景。把底层逻辑搞明白,上层应用才能写得稳。我在带新人时,都会让他们先做这个练习,效果很好。