From 2182e6e5870fbd406ebcd8b062ef495e0bf92143 Mon Sep 17 00:00:00 2001 From: San Nguyen Date: Wed, 23 Oct 2024 20:15:31 +0900 Subject: [PATCH] fix: socket.io upgrade sometimes happen before connect Signed-off-by: San Nguyen --- libs/react-client/src/useChatSession.ts | 28 +++++++++++-------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/libs/react-client/src/useChatSession.ts b/libs/react-client/src/useChatSession.ts index 94f8d74eb5..89030300da 100644 --- a/libs/react-client/src/useChatSession.ts +++ b/libs/react-client/src/useChatSession.ts @@ -133,32 +133,28 @@ const useChatSession = () => { // https://socket.io/docs/v4/how-it-works/#upgrade-mechanism // Require WebSocket when connecting to backend if (requireWebSocket) { - // https://socket.io/docs/v4/client-socket-instance/#socketio - // 'connect' event is emitted when the underlying connection is established with polling transport - // 'upgrade' event is emitted when the underlying connection is upgraded to WebSocket and polling request is stopped. - const engine = socket.io.engine; // https://github.com/socketio/socket.io/tree/main/packages/engine.io-client#events - engine.once('upgrade', () => { - // Set session on connect event, otherwise user can not interact with text input UI. - // Upgrade event is required to make sure user won't interact with the session before websocket upgrade success - socket.on('connect', onConnect); - }); // Socket.io will not retry upgrade request. // Retry upgrade to websocket when error can only be done via reconnect. // This will not be an issue for users if they are using persistent sticky session. // In case they are using soft session affinity like Istio, then sometimes upgrade request will fail - engine.once('upgradeError', () => { - onConnectError(); + socket.io.engine.once('upgradeError', () => { setTimeout(() => { socket.removeAllListeners(); socket.close(); - _connect({ - userEnv, - accessToken, - requireWebSocket - }); + _connect({ userEnv, accessToken, requireWebSocket }); }, 500); }); + + // https://socket.io/docs/v4/client-socket-instance/#socketio + socket.on('connect', () => { + // Sometimes upgrade request already succeeded before connect event + if (socket.io.engine.transport.name === 'websocket') { + onConnect(); + } else { + socket.io.engine.once('upgrade', onConnect); + } + }); } else { socket.on('connect', onConnect); }