Search code examples
javascripttypescriptblockchainweb3jsethers.js

ethers js websocket RPC keeps disconnecting when no events


I use ethers to connect to ethereum contract and listen for its events. This is how I set it up:

const provider = new ethers.WebSocketProvider(providerUrl);

const contract = new ethers.Contract(
  contractAddress,
  contractABI,
  provider
);

and after that I just connect to its events:

contract.removeAllListeners("EventName");


contract.on("EventName",(data)=>{
   ...rest of the code
})

I remove all events first to be sure there are no other listeners. When I get events constantly everything works fine. The problem is when I do not get any events for some time, usually like 30+ minutes with no event. It looks like it just stops and does not listen any more events and I have to restart the app. I've tried fixing it by adding a filter for all txs:

const filter = {
  fromBlock: "latest",
  toBlock: "latest",
  topics: [],
};

provider.on(filter, (log, event) => {});

but it doesn't work, it still disconnects. I've also tried to ping it by getting block number each few minutes but still nothing. I use ethers version 6.7.1. I cannot find any information about reconnecting to websockets. I found it in previous ethers version but it looks like it was removed in version 6.7.1. Any help is highly appreciated.


Solution

  • I fixed it finally by adding a wrapper for Websocket connection and reconnecting when it disconnects:

    function createWebSocket() {
      const ws = new WebSocket(process.env.WSS_PROVIDER);
    
      ws.on("close", () => {
        console.log("Disconnected. Reconnecting...");
        setTimeout(() => {
          provider = new ethers.WebSocketProvider(createWebSocket());
          startListening();
        }, 3000);
      });
    
      ws.on("error", (error) => {
        console.log("WebSocket error: ", error);
      });
    
      return ws;
    }
    
    let provider = new ethers.WebSocketProvider(createWebSocket());
    let contract;;
    
    function startListening() {
      contract = new ethers.Contract(
        "contractAddress",
        contractABI,
        provider
      );
    
      contract.removeAllListeners("Trade");
    
      contract
        .on("EventName", ()=>{
            ... rest of the code
        })
      }
    
    startListening()
    

    It works fine but for some reason it disconnects very often, looks like each 5-10 minutes when my provider (in this example Chainstack) should disconnect after 1 hour (reading their docs).

    enter image description here