diff --git a/aibox/frontend.html b/aibox/frontend.html
index a2c4b64..2c460ca 100644
--- a/aibox/frontend.html
+++ b/aibox/frontend.html
@@ -1355,6 +1355,8 @@
let reconnectAttempts = 0;
const MAX_RECONNECT_ATTEMPTS = 5;
let manualDisconnect = false;
+ let heartbeatTimer = null;
+ const HEARTBEAT_INTERVAL = 10000;
function connectWebSocket() {
const wsUrl = document.getElementById('ws-url').value.trim();
@@ -1379,6 +1381,13 @@
reconnectAttempts = 0;
updateConnectionStatus(true);
showSystemMessage(`✅ WebSocket 连接成功!服务器: ${wsUrl}`);
+ // 启动心跳保活,防止前置代理空闲超时断连
+ if (heartbeatTimer) clearInterval(heartbeatTimer);
+ heartbeatTimer = setInterval(() => {
+ if (webSocket.readyState === WebSocket.OPEN) {
+ webSocket.send(JSON.stringify({ type: 'ping' }));
+ }
+ }, HEARTBEAT_INTERVAL);
};
webSocket.onmessage = (event) => {
@@ -1399,6 +1408,7 @@
webSocket.onclose = (event) => {
console.log('WebSocket 断开连接:', event.code, event.reason);
+ if (heartbeatTimer) { clearInterval(heartbeatTimer); heartbeatTimer = null; }
updateConnectionStatus(false);
if (!manualDisconnect && reconnectAttempts < MAX_RECONNECT_ATTEMPTS) {
diff --git a/static/public/js/aibox.js b/static/public/js/aibox.js
index 41c48ba..101b2a8 100644
--- a/static/public/js/aibox.js
+++ b/static/public/js/aibox.js
@@ -44,8 +44,8 @@ let ws = null;
let manualClose = false; /* 手动断开则抑制自动重连 */
let reconnectDelay = RECONNECT_MIN;
let reconnectTimer = null;
-let heartbeatTimer = null; /* 心跳定时器,25s 发送 ping 保持 WS 连接 */
-const HEARTBEAT_INTERVAL = 25000; /* 心跳间隔(< gateway 30s 空闲超时) */
+let heartbeatTimer = null; /* 心跳定时器,10s 发送 ping 保持 WS 连接 */
+const HEARTBEAT_INTERVAL = 10000; /* 心跳间隔:需低于前置代理(Nginx/CDN)的 proxy_read_timeout */
function startHeartbeat() {
stopHeartbeat();