websocket心跳机制
心跳机制是指通过客户端向服务器(或者服务器向客户端)发送周期性的小消息来检测连接状态、防止连接因超时被关闭,以及维持连接活跃。
let socket = null;
let isConnected = false; // 连接状态标识
let heartbeatInterval = null; // 心跳发送定时器
let timeoutTimer = null; // 超时检测定时器
// 重连尝试的间隔延迟,单位:毫秒
const RECONNECT_DELAY = 5000;
const HEARTBEAT_INTERVAL = 10000; // 心跳间隔时间,单位:毫秒
const TIMEOUT = 15000; // 超时时间,大于心跳间隔时间
function connectWebSocket() {
// 创建 WebSocket 连接
socket = new WebSocket('ws://localhost:8080');
// 连接成功事件
socket.onopen = () => {
console.log('WebSocket connection is open.');
isConnected = true;
// 启动心跳机制
startHeartbeat();
};
// 处理接收到的消息
socket.onmessage = (event) => {
console.log('Message from server:', event.data);
if (event.data === 'pong') {
console.log('Received pong from server, connection is alive.');
// 如果收到服务器 pong,没有超时,清除超时检测定时器
resetTimeout();
}
};
// 处理连接关闭事件
socket.onclose = () => {
console.log('WebSocket connection closed. Retrying...');
clearHeartbeat(); // 停止心跳机制
isConnected = false;
// 尝试重连
setTimeout(connectWebSocket, RECONNECT_DELAY);
};
// 处理错误
socket.onerror = (error) => {
console.error('WebSocket encountered error:', error.message);
// 如果出错,关闭当前连接并尝试重连
socket.close();
};
}
// 心跳机制的启动
function startHeartbeat() {
if (heartbeatInterval) return; // 防止重复启动心跳
// 定期发送心跳 "ping" 消息
heartbeatInterval = setInterval(() => {
if (isConnected && socket.readyState === WebSocket.OPEN) {
console.log('Sending ping to server...');
socket.send('ping');
}
// 启动超时检测:等待服务器返回响应(pong)
startTimeout();
}, HEARTBEAT_INTERVAL);
}
// 启动超时检测
function startTimeout() {
clearTimeout(timeoutTimer); // 确保定时器不会重复堆叠
timeoutTimer = setTimeout(() => {
console.error('No response from server. Closing connection...');
if (socket.readyState === WebSocket.OPEN) {
socket.close(); // 主动关闭连接
}
}, TIMEOUT);
}
// 超时检测重置
function resetTimeout() {
clearTimeout(timeoutTimer); // 收到服务器响应后,清除当前超时定时器
}
// 停止心跳机制
function clearHeartbeat() {
clearInterval(heartbeatInterval);
clearTimeout(timeoutTimer);
heartbeatInterval = null;
timeoutTimer = null;
}
// 初始化 WebSocket 连接
connectWebSocket();
SSE
Server-Sent Events(简称 SSE)是一种浏览器原生支持的服务端推送技术。它允许服务端向浏览器单向发送实时更新数据,而客户端通过一个简单的 HTTP 长连接接收数据。SSE 是基于 HTTP 协议的,支持文本流传输,非常适合实时更新、实时通知等场景。
SSE 是一种轻量级的实时通信技术,与 WebSocket 相比,它只支持服务端到客户端的单向通信。它最初被提出用于 HTML5 标准,部分浏览器原生支持 SSE。
Server-Sent Events 的工作原理
客户端建立连接:
客户端通过 JavaScript 使用 EventSource 对象向服务器发起 HTTP 请求,服务端以流的形式持续发送事件数据。
保持长连接:
连接建立后,客户端保持和服务端的长连接,服务器不断向客户端推送事件。
自动重连:
如果连接断开(例如网络问题或服务端无法响应),客户端会自动尝试重新连接。
| 特点 | Server-Sent Events (SSE) | WebSocket |
|---|---|---|
| 通信方式 | 单向(服务端到客户端) | 双向(双向实时通信) |
| 协议 | 基于 HTTP/1.x | 独立的 WebSocket 协议 |
| 浏览器支持 | 广泛支持 | 较广泛支持 |
| 数据格式 | 纯文本 | 文本和二进制数据 |
| 使用复杂度 | 简单 | 更复杂,需要服务端支持 |
| 连接方式 | 使用 HTTP 长连接 | 单独的 WebSocket 协议连接 |