WebSocketProvider 处理 ws 关闭并重新连接
I think this is probably the best solution:
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)
})
}
This send a ping every 15 seconds, when it sends a ping, it expects a pong back within 7.5 seconds otherwise it closes the connection and calls the main startConnection function to start everything over.
Where it says // TODO: handle contract listeners setup + indexing that’s where you should do any indexing or listening for contract events etc.
Fine tune these timing vars to taste, depending on who your Node provider is, this are the settings I use for QuikNode
const EXPECTED_PONG_BACK = 15000
const KEEP_ALIVE_CHECK_INTERVAL = 7500
https://lightrun.com/answers/ethers-io-ethers-js-websocketprovider-handle-ws-close-and-reconnect