Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

websocket options #1040

Closed
tobyjaguar opened this issue Sep 10, 2020 · 14 comments
Closed

websocket options #1040

tobyjaguar opened this issue Sep 10, 2020 · 14 comments

Comments

@tobyjaguar
Copy link

Infura is telling me that I should ping the connection to keep it alive for websockets. They suggested using this options in web3:
https://web3js.readthedocs.io/en/v1.2.11/web3.html#providers

Is there comparable options in ethers that I can take advantage of?

@tobyjaguar
Copy link
Author

any traction on this?

@ricmoo
Copy link
Member

ricmoo commented Sep 17, 2020

Sorry, I haven't had a chance to look into this yet, I have a few other admin things I want to get to first.

Is the problem it disconnects after a short time? You may be able to use .on("block", () => { }) to keep the connection alive. I haven't personally had any issue with short-lived connections, but my purposes are generally at least slightly noisy...

@tobyjaguar
Copy link
Author

thanks for the response. Do you important stuff, just been going back and forth with infura trying to track down why one service loses connection, and the other doesn't. Both are connecting the same with ethers via websocket. My first attempt at a fix was the above, I too thought that might work. Infura recommends adding a keep-alive ping. I am still not sure what the issue here is, but I was curious if there was a comparable options. thanks

@ricmoo
Copy link
Member

ricmoo commented Sep 17, 2020

My gas-ticker stays connected for hours at a time, but I do use that serve-forever.sh script to make sure it keeps on trucking... Maybe a band-aid solution for now though...

@tobyjaguar
Copy link
Author

I will look into this, thank you. And I do need to write some reconciliation script to re-connect if it gets severed. I'll take a look, thanks again.

@rymnc
Copy link

rymnc commented Oct 21, 2020

@tobyjaguar you can use the web3-providers-ws package and pass it in as a Web3Provider to ethers
the web3-providers-ws package has many options such as reconnect, keep alive,etc
Here

@tobyjaguar
Copy link
Author

tobyjaguar commented Oct 21, 2020

Interesting. I ended up writing a heartbeat function into my process as there are many reconnects with infura. But this looks promising as a more permanent solution. Would need to resubscribe to events on reconnect. I will look into it. Thank you.

@rymnc
Copy link

rymnc commented Oct 21, 2020

yeah you can probably submit a pr to the web3-providers-ws package that auto subscribes on reconnect!

@b10c77
Copy link

b10c77 commented Jan 16, 2021

@tobyjaguar can you share your heartbeat function? I'm on the same boat, looking to re-connect ethers.js web socket in case the connection is dropped. Thanks!

@tobyjaguar
Copy link
Author

I never explored @rymnc 's suggestion regarding the options of the web3-providers-ws package:

      // Useful to keep a connection alive
      keepalive: true,
      keepaliveInterval: 60000 // ms

That is probably a better way to go, but I had already attempted a heartbeat process. After tinkering with it for a couple weeks this seems to work for my purposes. It is probably a bit overkill, but I grab a beat tolerance from config, register a timestamp and then just continuously consume the heartbeat function().

function updateTimestamp() {
  provider.on("block", async block => {
    lastTimestamp = moment();
    //(lastTimestamp) ? console.log(`time: ${lastTimestamp}`) : null;
  })
}

async function heartbeat() {
  //check if our lastTimestamp is before now minus 10 seconds ago, if after we lost sync
  if (lastTimestamp && (lastTimestamp.isBefore(moment().subtract(((beat/PER_SECOND)+1), 'seconds')))) {
    console.log("lost connection to provider, attempting to reset...");

    // get the latest provider we have saved
    //provider = getProvider();

    // remove all listeners subscribed
    provider.removeAllListeners();

    // we should not have any listeners
    console.log(`listeners: ${provider.listenerCount()}`);

    // destroy connection
    await provider.destroy();

    // reconnection to provider
    setProvider();

    // save provider locally
    provider = getProvider();

    // register all out listeners
    require('./registerEvents')();
    console.log(`listeners: ${provider.listenerCount()}`);

    // update our lastTimestamp
    lastTimestamp = moment();
    console.log(`time: ${lastTimestamp}`);
    updateTimestamp();
  }
  await sleep(beat);
  heartbeat();
}

The above has kept my processes online since I implemented the above. Things go horribly wrong if the process loses the internet connection, but it can heal a lost connection with infura, which seems to happen all the time.

@rymnc
Copy link

rymnc commented Jan 17, 2021

I think it would be best if someone extended the websocket provider/made a pr on the existing one which handles websocket reconnections + resubscriptions etc!

@tobyjaguar
Copy link
Author

alright, my band-aid solution doesn't work so well on L2 as those blocks are inconsistent.
@rymnc with your recommendation of using web3-providers-ws, would I pass the instantiated client to ethers like so:
provider = new ethers.providers.WebSocketProvider(wsProvider);

This is how I am currently connecting to L2, until infura catches up.

@tobyjaguar
Copy link
Author

@smartins don't know if you ever got a keepalive function going, but I have had success with this design:
#1053 (comment)

thanks to @mikevercoelen for posting

@Ailein
Copy link

Ailein commented Jun 3, 2021

@tobyjaguar I also face this kind of problem, Can you post your code

@ethers-io ethers-io locked and limited conversation to collaborators Aug 24, 2021
@ricmoo ricmoo closed this as completed Aug 24, 2021

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants