Skip to content

Conversation

danielkalen
Copy link

#38 pull request which I created only handles reconnecting on error events but after using that branch in production env I quickly realized that there are many cases in which the connection gets disconnected for whatever reason and doesn't emit an error event but rather just a close event. This branch is modified to handle these close events and also distinguishes between a user-invoked close event and a non-user-invoked closed event.

@danielkalen danielkalen mentioned this pull request Jan 29, 2018
@coveralls
Copy link

coveralls commented Jan 29, 2018

Coverage Status

Coverage decreased (-25.5%) to 68.077% when pulling 3f0f774 on danielkalen:reconnecting-websocket-onclose into 865ad1a on HyperCubeProject:master.

}
}

let closedManually = false
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a fan of this hacky flag. Shouldn't we check the code of the event emitted on close and infer if it has been triggered manually or not? Referring to section 7.4.1 of RFC6455.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Neither am I, and initially I was implementing this with using a code but after seeing the amount of possible values for the code we need to check + the uncertainty of what codes we'll get working with binance's unstable servers + the general instability of websockets api + the difficulty of testing this + lack of time in my hands I see this simple approach as much more efficient, simpler, and easier to understand than trying to be spec compliant

src/websocket.js Outdated
}

let closedManually = false
let w = newSocket(path, cb, onClose)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

w should be defined before onClose in this scope

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are you saying it should be defined or declared before onClose? Because it cannot be defined before onClose as we need to pass onClose as one of the parameters to newSocket()

src/websocket.js Outdated


const createSocket = (path, cb) => {
const onClose = ()=> {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might want to run prettier too

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it 👍

})

return () => cache.forEach(w => w.close())
return () => cache.forEach(close => close())
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per #36, I'm thinking it might be interesting to return an object exposing this clean function + the websockets array for advanced users, thoughts?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure that'll be useful but as I mentioned before the problem with this approach is that it's going to break any apps using the existing api with the close callbacks as this is not backwards compatible. Plus, if the purpose of returning the websocket object back to the caller is so that the caller can handle errors and reconnect by himself then it won't be necessary if reconnection is handled internally by this lib (which I think it should)

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can do a major release, that's not a big deal


const newSocket = (path, cb, onClose) => {
const w = new WebSocket(`${BASE}/${path}`)
const onDisconnect = () => setTimeout(onClose, RECONNECT_DELAY)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason not to reconnect instantly?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because binance's servers have proven to be awfully unstable and at times down for hours. If we do not apply a delay we can potentially cause a huge overload if their servers are down and we are constantly trying to reconnect. If their servers are down for 1 minute and are immediatly rejecting the connection we can know that with the 1s delay we will be instantiating ~50 websocket instances/attempted connections while if we don't apply a delay we can be looking (and considering it takes 10ms to create a websocket and emit a connection) we will be looking at ~6000 attempted connections in that 1min.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True

@balthazar
Copy link
Owner

What do you think of sockette, a ws wrapper automatically handling reconnection? I'm thinking of using this instead

@bennycode
Copy link
Contributor

What do you think of sockette, a ws wrapper automatically handling reconnection? I'm thinking of using this instead

+1 for reusing existing libraries. Here is another challenger: reconnecting-websocket

@balthazar
Copy link
Owner

Thanks for your help! Very sorry about the delay, and I'll to close in favor of #49 which is tested

@balthazar balthazar closed this Mar 5, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants