fix: 优化网页端不能连接的问题

This commit is contained in:
2026-07-17 21:14:45 +08:00
parent b8edd5eff5
commit 0cb6b75a54
5 changed files with 110 additions and 22 deletions

View File

@@ -7,7 +7,12 @@ import { WebSocketServer } from 'ws';
const PORT = Number(process.env.PORT || 8088);
const PATH = process.env.WS_PATH || '/ws/signal';
const wss = new WebSocketServer({ port: PORT, path: PATH });
const wss = new WebSocketServer({
port: PORT,
path: PATH,
// WebRTC SDP 消息可能较大,将最大负载设为 1MB默认 100MB 但在某些代理环境下受限)
maxPayload: 1024 * 1024,
});
// deviceId -> { ws, type }
const sessions = new Map();
@@ -17,10 +22,34 @@ const pending = new Map();
const keyOf = (a, b) => `${a}->${b}`;
function send(ws, obj) {
if (ws && ws.readyState === ws.OPEN) ws.send(JSON.stringify(obj));
if (ws && ws.readyState === ws.OPEN) {
try {
ws.send(JSON.stringify(obj));
} catch (e) {
console.error('[send] 发送消息失败:', e.message);
}
}
}
// —— 服务端主动 ping/pong 保活:每 30 秒向所有连接发送 ping
// 若 60 秒内未收到 pong 则强制关闭连接(防止僵死连接占用资源)。
const HEARTBEAT_INTERVAL = 30_000;
const heartbeatTimer = setInterval(() => {
wss.clients.forEach((ws) => {
if (ws._alive === false) {
console.warn('[heartbeat] 连接无响应,强制关闭');
return ws.terminate();
}
ws._alive = false;
try { ws.ping(); } catch { /* ignore */ }
});
}, HEARTBEAT_INTERVAL);
wss.on('close', () => clearInterval(heartbeatTimer));
wss.on('connection', (ws) => {
ws._alive = true;
ws.on('pong', () => { ws._alive = true; });
ws.on('message', (data) => {
let msg;
try {
@@ -29,6 +58,8 @@ wss.on('connection', (ws) => {
return;
}
const type = (msg.type || '').toUpperCase();
// 忽略客户端心跳 ping仅用于保活
if (type === 'PING') return;
switch (type) {
case 'REGISTER': handleRegister(ws, msg); break;
case 'DEVICE_LIST': handleDeviceList(ws); break;