Commitf1d6c34dRecorded14 Jul 2026Repositorysigil-websocket

ws-receive: return #f for a still-CONNECTING browser socket, not 'closed

Message

On WASM the browser WebSocket opens asynchronously, so ws-connected? is #f during the CONNECTING window as well as after CLOSE (ws-connect sets state 'open optimistically; the raw socket reaches readyState OPEN later). ws-receive reported both as 'closed, and irc-ws-receive latched the session dead on the first poll that landed before the socket finished opening -- fatal on higher-latency links (phone/VPN ~455ms open) though never hit on localhost (~31ms). Consult the new wasm-websocket-connecting? (readyState) so a connecting socket returns #f ("no data yet") and only a genuine close returns 'closed. Native path unchanged (guarded by cond-expand).

Changed
 src/sigil/websocket/connection.sgl | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)
Diff
src/sigil/websocket/connection.sglmodified
@@ -528,7 +528,22 @@
528
(define (ws-receive conn)
529
(: ws-connection? -> any?)
530
(if (not (ws-connected? conn))
531
'closed
+531
(cond-expand
+532
(wasm
+533
;; The browser WebSocket opens ASYNChronously, so ws-connected?
+534
;; is #f during the CONNECTING window as well as after CLOSE
+535
;; (ws-connect sets state 'open optimistically; the raw socket
+536
;; reaches readyState OPEN later). Consult the readyState to tell
+537
;; them apart: a still-connecting socket returns #f ("no data
+538
;; yet"), only a genuinely closed socket returns 'closed. Without
+539
;; this, the first poll that lands before the socket finishes
+540
;; opening reports 'closed and latches the session dead — the
+541
;; browser slow-open bug (never hit on localhost's ~31ms open,
+542
;; fatal over phone/VPN's ~455ms).
+543
(if (wasm-websocket-connecting? (ws-connection-socket conn))
+544
#f
+545
'closed))
+546
(else 'closed))
547
(cond-expand
548
(wasm
549
(let ((result (process-wasm-event