From e1b532d48afa1713946977e821ffc84ec72881d8 Mon Sep 17 00:00:00 2001 From: James Smith Date: Wed, 18 Mar 2026 20:40:15 +0000 Subject: [PATCH] Fix SSE first-byte delay in ADS-B and controller streams; harden WebSocket init - Add immediate keepalive to /adsb/stream generator so the Werkzeug dev server flushes response headers immediately on tracking start, preventing the 30-second delay before the aircraft map begins receiving data - Same fix for /controller/stream/all used by the ADSB dashboard in agent mode - Widen WebSocket init exception guards in app.py from ImportError to Exception so any startup failure (e.g. RuntimeError from flask-sock on an unsupported WSGI server) is caught instead of propagating Co-Authored-By: Claude Sonnet 4.6 --- app.py | 10 +++++----- routes/adsb.py | 3 +++ routes/controller.py | 1 + 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/app.py b/app.py index 7a8f61d..c9a6550 100644 --- a/app.py +++ b/app.py @@ -1128,35 +1128,35 @@ def _init_app() -> None: try: from routes.audio_websocket import init_audio_websocket init_audio_websocket(app) - except ImportError: + except Exception: pass # Initialize KiwiSDR WebSocket audio proxy try: from routes.websdr import init_websdr_audio init_websdr_audio(app) - except ImportError: + except Exception: pass # Initialize WebSocket for waterfall streaming try: from routes.waterfall_websocket import init_waterfall_websocket init_waterfall_websocket(app) - except ImportError: + except Exception: pass # Initialize WebSocket for meteor scatter monitoring try: from routes.meteor_websocket import init_meteor_websocket init_meteor_websocket(app) - except ImportError: + except Exception: pass # Initialize WebSocket for ground station live waterfall try: from routes.ground_station import init_ground_station_websocket init_ground_station_websocket(app) - except ImportError: + except Exception: pass # Defer heavy/network operations so the worker can serve requests immediately diff --git a/routes/adsb.py b/routes/adsb.py index 3b7d8c9..710db27 100644 --- a/routes/adsb.py +++ b/routes/adsb.py @@ -1167,6 +1167,9 @@ def stream_adsb(): def generate(): last_keepalive = time.time() + # Send immediate keepalive so Werkzeug dev server flushes response + # headers right away (it buffers until first body byte is written). + yield format_sse({'type': 'keepalive'}) try: while True: diff --git a/routes/controller.py b/routes/controller.py index 8d0a9a0..166e312 100644 --- a/routes/controller.py +++ b/routes/controller.py @@ -673,6 +673,7 @@ def stream_all_agents(): def generate() -> Generator[str, None, None]: last_keepalive = time.time() keepalive_interval = 30.0 + yield format_sse({'type': 'keepalive'}) try: while True: