@@ -22,6 +22,7 @@ const CHAT_FEED_LIMIT = 100;
2222const ALERTS_FEED_LIMIT = 80 ;
2323const EVENT_LOG_LIMIT = 100 ;
2424const VIEWER_POLL_INTERVAL_MS = 30000 ;
25+ const SOCKET_CONNECT_TIMEOUT_MS = 8000 ;
2526const SOCKET_CONNECTED_EVENT_TIMEOUT_MS = 4000 ;
2627const SSE_RECONNECT_DELAY_MS = 3000 ;
2728const VELORA_EMOTE_MAP = {
@@ -1033,6 +1034,8 @@ function connectSse(reason) {
10331034 if ( xhr . readyState === 2 && xhr . status && xhr . status !== 200 ) {
10341035 setSocketStatus ( 'error' ) ;
10351036 addEventLogEntry ( `SSE connection failed: HTTP ${ xhr . status } ` , 'error' ) ;
1037+ } else if ( xhr . readyState === 2 && xhr . status === 200 && ! state . eventsConnected ) {
1038+ applyConnectedChannelInfo ( null , 'SSE' ) ;
10361039 }
10371040 } ;
10381041
@@ -1082,6 +1085,16 @@ function startSocketFallbackTimer() {
10821085
10831086// ─── Socket.IO connection ─────────────────────────────────────────────────────
10841087
1088+ function startSocketConnectTimeout ( ) {
1089+ clearSocketFallbackTimer ( ) ;
1090+ state . socketFallbackTimer = setTimeout ( function ( ) {
1091+ if ( state . eventsConnected || state . sseRequest ) {
1092+ return ;
1093+ }
1094+ connectSse ( 'Velora WebSocket connection timed out. Falling back to SSE.' ) ;
1095+ } , SOCKET_CONNECT_TIMEOUT_MS ) ;
1096+ }
1097+
10851098function connectSocket ( ) {
10861099 if ( ! state . tokens ?. access_token ) return ;
10871100 if ( typeof io !== 'function' ) {
@@ -1103,6 +1116,7 @@ function connectSocket() {
11031116
11041117 state . socket = socket ;
11051118 setSocketStatus ( 'connecting' ) ;
1119+ startSocketConnectTimeout ( ) ;
11061120
11071121 socket . on ( 'connect' , ( ) => {
11081122 setSocketStatus ( 'connecting' ) ;
0 commit comments