Open
Description
Ethers Version
6.5.1
Search Terms
Describe the Problem
The problem is that the websocket hangs after a period of inactivity. This issue has been discussed in #1053
In particular, the fix is:
#1053 (comment)
const EXPECTED_PONG_BACK = 15000
const KEEP_ALIVE_CHECK_INTERVAL = 7500
export const startConnection = () => {
provider = new ethers.providers.WebSocketProvider(config.ETH_NODE_WSS)
let pingTimeout = null
let keepAliveInterval = null
provider._websocket.on('open', () => {
keepAliveInterval = setInterval(() => {
logger.debug('Checking if the connection is alive, sending a ping')
provider._websocket.ping()
// Use `WebSocket#terminate()`, which immediately destroys the connection,
// instead of `WebSocket#close()`, which waits for the close timer.
// Delay should be equal to the interval at which your server
// sends out pings plus a conservative assumption of the latency.
pingTimeout = setTimeout(() => {
provider._websocket.terminate()
}, EXPECTED_PONG_BACK)
}, KEEP_ALIVE_CHECK_INTERVAL)
// TODO: handle contract listeners setup + indexing
})
provider._websocket.on('close', () => {
logger.error('The websocket connection was closed')
clearInterval(keepAliveInterval)
clearTimeout(pingTimeout)
startConnection()
})
provider._websocket.on('pong', () => {
logger.debug('Received pong, so connection is alive, clearing the timeout')
clearInterval(pingTimeout)
})
}
The ping()
function is missing from the websocket object.
export interface WebSocketLike {
onopen: null | ((...args: Array<any>) => any);
onmessage: null | ((...args: Array<any>) => any);
onerror: null | ((...args: Array<any>) => any);
readyState: number;
send(payload: any): void;
close(code?: number, reason?: string): void;
}
Not sure if there's a correct way to sustain the websocket connection, but the code snippet above from #1053 (comment) seems to be the only feasible way.
Code Snippet
No response
Contract ABI
No response
Errors
No response
Environment
No response
Environment (Other)
No response