From 7b5337383b2470252600e6554c4fd0f7c6e21b00 Mon Sep 17 00:00:00 2001 From: swpa Date: Mon, 18 May 2026 15:40:19 +0800 Subject: [PATCH] fix: To resolve SSE (Server-Sent Events) issue "Waiting for connections to close." --- routers/leaf_options.py | 14 ++++++++++---- static/app.js | 8 ++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/routers/leaf_options.py b/routers/leaf_options.py index 3048e7e..967fe26 100644 --- a/routers/leaf_options.py +++ b/routers/leaf_options.py @@ -41,14 +41,20 @@ async def sse_stream(request: Request): async def event_generator(): try: while True: + # 🌟 每次迴圈先檢查前端是否已經斷線 (按了 F5) + if await request.is_disconnected(): + break try: - message = await asyncio.wait_for(client_queue.get(), timeout=2.0) + # 縮短 timeout 為 1 秒,讓檢查更靈敏 + message = await asyncio.wait_for(client_queue.get(), timeout=1.0) yield message except asyncio.TimeoutError: - if await request.is_disconnected(): - break - # 🌟 關鍵修復 2:每 2 秒發送一個空註解,防止瀏覽器因閒置而自動斷線 yield ": keepalive\n\n" + + except asyncio.CancelledError: + # 🌟 關鍵修復:當 Uvicorn 觸發 reload 關閉伺服器時,會拋出此例外 + # 我們捕捉它並默默退出,不讓伺服器卡住 + pass finally: active_clients.discard(client_queue) diff --git a/static/app.js b/static/app.js index 37004d0..780323e 100644 --- a/static/app.js +++ b/static/app.js @@ -93,6 +93,14 @@ function initGlobalSSE() { }; } +// 🌟 關鍵修復:當使用者按 F5 重整或關閉網頁時,主動切斷 SSE 連線 +window.addEventListener('beforeunload', () => { + if (globalSSE) { + globalSSE.close(); + globalSSE = null; + } +}); + // 頁面載入與縮放初始化 window.onload = () => { initTerminal();