From 56618a6655db4c6ba2bf24a06a88fa088cbff0b2 Mon Sep 17 00:00:00 2001 From: dekun Date: Fri, 14 Aug 2026 18:10:54 +0800 Subject: [PATCH] Harden embed live refresh with reconnect backoff and poll fallback. Document Nginx SSE proxy settings for long-lived live streams. Co-authored-by: Cursor --- lib/common/static/instance_live.js | 30 ++++++++++++++++++++++--- lib/instance/templates/embed_shell.html | 2 +- 部署文档.md | 18 +++++++++++++++ 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/lib/common/static/instance_live.js b/lib/common/static/instance_live.js index f51b3be..5cefd7e 100644 --- a/lib/common/static/instance_live.js +++ b/lib/common/static/instance_live.js @@ -1,5 +1,6 @@ /** * embed 壳:SSE 收到后台 tick 后拉 JSON 快照更新 DOM,切换 tab 不再重复请求 HTML. + * 另有可见性恢复 + SSE 断开时的轮询兜底,避免经 Nginx 几分钟后停刷. */ (function (global) { let liveEventSource = null; @@ -7,6 +8,8 @@ let localLiveVersion = -1; let sseConnected = false; let refreshTimer = null; + let fallbackTimer = null; + let reconnectAttempt = 0; function isEmbedShell() { return document.body && document.body.getAttribute("data-embed-shell") === "1"; @@ -16,7 +19,7 @@ if (global.InstanceEmbed && typeof global.InstanceEmbed.getTab === "function") { return global.InstanceEmbed.getTab(); } - return document.body.getAttribute("data-page") || "trade"; + return document.body.getAttribute("data-page") || "options"; } function refreshTabData(tab, opts) { @@ -30,7 +33,9 @@ if (tab === "options" && global.OptionsPanelLive && typeof global.OptionsPanelLive.refreshSoft === "function") { global.OptionsPanelLive.refreshSoft(options); } - // 数据看板自有 SSE + 快照,不跟 embed live tick 重拉. + if (tab === "hedge_plan" && global.HedgePlanLive && typeof global.HedgePlanLive.refreshSoft === "function") { + global.HedgePlanLive.refreshSoft(options); + } } function scheduleRefresh(opts) { @@ -76,23 +81,42 @@ liveEventSource.addEventListener("live", function (ev) { try { onLiveEvent(JSON.parse(ev.data || "{}")); + reconnectAttempt = 0; } catch (_) {} }); liveEventSource.onopen = function () { sseConnected = true; + reconnectAttempt = 0; }; liveEventSource.onerror = function () { sseConnected = false; closeLiveStream(); + reconnectAttempt += 1; + var delay = Math.min(30000, 3000 + reconnectAttempt * 2000); liveReconnectTimer = setTimeout(function () { connectLiveStream(); - }, 8000); + }, delay); }; } + function ensureFallbackPoll() { + if (fallbackTimer) return; + // SSE 正常时也做低频兜底;断开时依赖它持续刷新 + fallbackTimer = setInterval(function () { + if (document.hidden) return; + scheduleRefresh({ force: !sseConnected }); + }, sseConnected ? 20000 : 8000); + } + function startLive() { if (!isEmbedShell()) return; connectLiveStream(); + ensureFallbackPoll(); + document.addEventListener("visibilitychange", function () { + if (document.hidden) return; + if (!sseConnected) connectLiveStream(); + scheduleRefresh({ force: true }); + }); } global.InstanceLive = { diff --git a/lib/instance/templates/embed_shell.html b/lib/instance/templates/embed_shell.html index ce432b6..ed268c1 100644 --- a/lib/instance/templates/embed_shell.html +++ b/lib/instance/templates/embed_shell.html @@ -145,7 +145,7 @@ const ORDER_ENTRY_MODEL_CODE_TO_CATEGORY = {{ entry_model_code_to_category | toj window.__INSTANCE_DISPLAY__ = {{ display | tojson }}; - + diff --git a/部署文档.md b/部署文档.md index f633a08..a1e9c28 100644 --- a/部署文档.md +++ b/部署文档.md @@ -177,6 +177,24 @@ bash /opt/crypto_okx/deploy/manage.sh # 选 2 - **页面打不开**:`pm2 status` / `pm2 logs crypto_okx --lines 50` - **OKX 失败**:先确认 SOCKS `ss -lntp | grep 1080`,再 `curl --proxy socks5h://...` - **脚本 `pipefail` 报错**(Windows 编辑过):`sed -i 's/\r$//' deploy/*.sh deploy/lib/*.sh` +- **几分钟后资金/行情不自动刷新**:embed 壳靠 SSE(`/api/instance/live/stream`).若前面有 Nginx,需关闭缓冲并拉长超时,例如: + +```nginx +location / { + proxy_pass http://127.0.0.1:5004; + proxy_http_version 1.1; + proxy_set_header Connection ""; + proxy_buffering off; + proxy_read_timeout 3600s; + proxy_send_timeout 3600s; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; +} +``` + +改完后 `nginx -t && systemctl reload nginx`,浏览器强刷.前端另有断开重连与轮询兜底. ---