Skip to content
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

Websockets drop connection after period of inactivity? Is this a valid fallback/fix? #117

Closed
sanaterrae opened this issue Jun 16, 2018 · 7 comments

Comments

@sanaterrae
Copy link

sanaterrae commented Jun 16, 2018

Hey all,

I'm using Infura's wss://ropsten.infura.io/_ws Ropsten websocket to listen to events from my contract server-side. I've noticed it works great until a period of inactivity. Then I get the error which points to the websocket dropping the connection:

2018-06-16T16:15:04.200899+00:00 app[web.1]: /app/node_modules/web3/packages/web3-providers-ws/node_modules/websocket/lib/W3CWebSocket.js:111
2018-06-16T16:15:04.200915+00:00 app[web.1]: throw new Error('cannot call send() while not connected');
2018-06-16T16:15:04.200918+00:00 app[web.1]: ^
2018-06-16T16:15:04.200920+00:00 app[web.1]:
2018-06-16T16:15:04.200922+00:00 app[web.1]: Error: cannot call send() while not connected
2018-06-16T16:15:04.200924+00:00 app[web.1]: at W3CWebSocket.send (/app/node_modules/web3/packages/web3-providers-ws/node_modules/websocket/lib/W3CWebSocket.js:111:15)
2018-06-16T16:15:04.200926+00:00 app[web.1]: at WebsocketProvider.send (/app/node_modules/web3/packages/web3-providers-ws/src/index.js:213:21)
2018-06-16T16:15:04.200929+00:00 app[web.1]: at WebsocketProvider.OverUnder.currentProvider.sendAsync (/app/index.js:73:50)
2018-06-16T16:15:04.200930+00:00 app[web.1]: at RequestManager.send (/app/node_modules/web3/packages/web3-core-requestmanager/src/index.js:129:66)
2018-06-16T16:15:04.200932+00:00 app[web.1]: at RequestManager.removeSubscription (/app/node_modules/web3/packages/web3-core-requestmanager/src/index.js:209:14)
2018-06-16T16:15:04.200933+00:00 app[web.1]: at Object.callback (/app/node_modules/web3/packages/web3-core-subscriptions/src/subscription.js:273:50)
2018-06-16T16:15:04.200935+00:00 app[web.1]: at /app/node_modules/web3/packages/web3-core-requestmanager/src/index.js:106:49
2018-06-16T16:15:04.200937+00:00 app[web.1]: at Array.forEach ()
2018-06-16T16:15:04.200938+00:00 app[web.1]: at requestManagerNotification (/app/node_modules/web3/packages/web3-core-requestmanager/src/index.js:104:50)
2018-06-16T16:15:04.200940+00:00 app[web.1]: at /app/node_modules/web3/packages/web3-providers-ws/src/index.js:106:17
2018-06-16T16:15:04.200942+00:00 app[web.1]: at Array.forEach ()
2018-06-16T16:15:04.200943+00:00 app[web.1]: at W3CWebSocket.connection.onclose (/app/node_modules/web3/packages/web3-providers-ws/src/index.js:104:16)
2018-06-16T16:15:04.200946+00:00 app[web.1]: at W3CWebSocket._dispatchEvent [as dispatchEvent] (/app/node_modules/web3/packages/web3-providers-ws/node_modules/yaeti/lib/EventTarget.js:107:17)
2018-06-16T16:15:04.200949+00:00 app[web.1]: at W3CWebSocket.onClose (/app/node_modules/web3/packages/web3-providers-ws/node_modules/websocket/lib/W3CWebSocket.js:228:10)
2018-06-16T16:15:04.200950+00:00 app[web.1]: at WebSocketConnection. (/app/node_modules/web3/packages/web3-providers-ws/node_modules/websocket/lib/W3CWebSocket.js:201:17)
2018-06-16T16:15:04.200952+00:00 app[web.1]: at WebSocketConnection.emit (events.js:180:13)
2018-06-16T16:15:04.200953+00:00 app[web.1]: at WebSocketConnection.handleSocketClose (/app/node_modules/web3/packages/web3-providers-ws/node_modules/websocket/lib/WebSocketConnection.js:387:14)
2018-06-16T16:15:04.200955+00:00 app[web.1]: at TLSSocket.emit (events.js:185:15)
2018-06-16T16:15:04.200956+00:00 app[web.1]: at _handle.close (net.js:541:12)
2018-06-16T16:15:04.200957+00:00 app[web.1]: at TCP.done [as _onclose] (_tls_wrap.js:379:7)

This may be a similar issue to #97 and #80 . #80 references a way to stop this from happening by pinging the websocket at an interval to stop it from dropping the connection. Does this mean the connection will only be dropped if the connection is idle for a period of time? Also is @woniesong92 's idea:

Quote: "
@egalano from the server side, is pong() supported?

AFAIK the client side should just do something like this, right?

setInterval(() => {
  ws.send('__ping__');
}, 30000)

"

A solution/fix to this? If so could someone point me on how about to do this client-side? Or if it isn't, please point me to any solution! Is MetaMasks InPageProvider polyfill subscription still supported in web3 1.0.0? I've heard that is a potential solution but have been unable to find information on how to implement it.

Thanks all, I understand websockets aren't production ready so I'm looking for a fallback to stop my dApp from crashing. Thanks to the great work by the Infura team as well, your services are extremely helpful, can't wait for websockets to be production ready!

EDIT: Also I just switched to using wss://ropsten.infura.io/_ws from wss://ropsten.infura.io/ws after seeing comments about the ".../_ws" being stabler. Not sure if this changes anything.

@sanaterrae sanaterrae changed the title Websockets drop connection after period of inactivity? Websockets drop connection after period of inactivity? Is this a valid fallback/fix? Jun 16, 2018
@JeeChoi
Copy link

JeeChoi commented Jul 30, 2018

Hello, any websocket connection that goes idle for over an hour is disconnected. Setting up the client to send pings will prevent the connection from going idle, but I believe that is dependent on what the browser supports, and not the client code.

@sanaterrae
Copy link
Author

Hey @JeeChoi , thanks for the clarification! I'll try that out as a solution.

@Dominator008
Copy link

@JeeChoi What counts as a "ping"? I've tried eth_getBlockByNumber which doesn't seem to be working. My connection is still cut off after an hour.

@ryanschneider
Copy link

@Dominator008 we are referring to ping control frames as per the RFC:

https://tools.ietf.org/html/rfc6455#section-5.5.2

How you generate ping control frames would depend on your client library.

However, sending any standard traffic should work to keep the connection open as well. Are you disconnected exactly an hour after first connecting, or an hour after your last sent message?

@Dominator008
Copy link

Sorry it was not "after an hour". The connection remained open for more than an hour and I ping eth_getBlockByNumber every few seconds, but I still got disconnected at about 04:07 PST. Is it just a flake then?

@ryanschneider
Copy link

@Dominator008 yes you can be disconnected for multiple reasons, so should be prepared to reconnect in your code. The reasons include but are not limited to:

  • Maintenance on our end
  • We detect an issue with the ethereum node you are getting subscription information from
  • network issues between your client and our backend

Ideally we'd like to notify users of such disconnects by emitting events on the websocket before doing so, but since that's not part of the ethereuem JSONRPC sub/pub spec we found that it could confuse end-user applications if we emitted custom events, so we currently don't have a good means to notify the user about the need to disconnect them.

@Dominator008
Copy link

@ryanschneider Thanks for the clarification!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants