diff --git a/.changeset/lazy-turkeys-burn.md b/.changeset/lazy-turkeys-burn.md new file mode 100644 index 0000000000..9263cf679b --- /dev/null +++ b/.changeset/lazy-turkeys-burn.md @@ -0,0 +1,5 @@ +--- +"viem": patch +--- + +Fixed reconnection logic for WebSocket clients. diff --git a/src/utils/rpc/socket.ts b/src/utils/rpc/socket.ts index 6cf5eb46a9..0d5a4144c7 100644 --- a/src/utils/rpc/socket.ts +++ b/src/utils/rpc/socket.ts @@ -132,6 +132,27 @@ export async function getSocketRpcClient( let socket: Socket<{}> let keepAliveTimer: ReturnType | undefined + let reconnectInProgress = false + function attemptReconnect() { + // Attempt to reconnect. + if (reconnect && reconnectCount < attempts) { + if (reconnectInProgress) return + reconnectInProgress = true + reconnectCount++ + // Make sure the previous socket is definitely closed. + socket?.close() + setTimeout(async () => { + await setup().catch(console.error) + reconnectInProgress = false + }, delay) + } + // Otherwise, clear all requests and subscriptions. + else { + requests.clear() + subscriptions.clear() + } + } + // Set up socket implementation. async function setup() { const result = await getSocket({ @@ -142,17 +163,7 @@ export async function getSocketRpcClient( for (const subscription of subscriptions.values()) subscription.onError?.(new SocketClosedError({ url })) - // Attempt to reconnect. - if (reconnect && reconnectCount < attempts) - setTimeout(async () => { - reconnectCount++ - await setup().catch(console.error) - }, delay) - // Otherwise, clear all requests and subscriptions. - else { - requests.clear() - subscriptions.clear() - } + attemptReconnect() }, onError(error_) { error = error_ @@ -162,20 +173,7 @@ export async function getSocketRpcClient( for (const subscription of subscriptions.values()) subscription.onError?.(error) - // Make sure socket is definitely closed. - socketClient?.close() - - // Attempt to reconnect. - if (reconnect && reconnectCount < attempts) - setTimeout(async () => { - reconnectCount++ - await setup().catch(console.error) - }, delay) - // Otherwise, clear all requests and subscriptions. - else { - requests.clear() - subscriptions.clear() - } + attemptReconnect() }, onOpen() { error = undefined