Fix WebSocket handler exiting immediately on receive timeout

simple-websocket 1.1.0's receive(timeout=N) returns None on timeout
instead of raising TimeoutError. The handler treated None as
"connection closed" and broke out of the loop, causing Werkzeug to
write its HTTP 200 response on the still-open WebSocket socket.
The browser saw those HTTP bytes as an invalid WebSocket frame.

Now checks ws.connected to distinguish timeout (None + connected)
from actual close (None + not connected).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Smittix
2026-02-08 13:21:25 +00:00
parent 01f3cc845b
commit 37842dc1ef

View File

@@ -105,19 +105,22 @@ def init_waterfall_websocket(app: Flask):
try:
msg = ws.receive(timeout=0.1)
except TimeoutError:
if stop_event.is_set():
break
continue
except Exception as e:
if "closed" in str(e).lower():
err = str(e).lower()
if "closed" in err:
break
if "timed out" not in str(e).lower():
if "timed out" not in err:
logger.error(f"WebSocket receive error: {e}")
continue
if msg is None:
break
# simple-websocket returns None on timeout AND on
# close; check ws.connected to tell them apart.
if not ws.connected:
break
if stop_event.is_set():
break
continue
try:
data = json.loads(msg)