-
Notifications
You must be signed in to change notification settings - Fork 3k
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
Can't get Node to emit connect_failed or reconnect_failed if server is down #311
Comments
Oh, one more thing. To get the reconnect logic to even fire, you need to apply 3rd-Edens one-line patch to prevent Node errors from bubbling up: After that, you will get the reconnecting events (but not connect_failed / reconnect_failed) |
I found the following useful to receive connect_failed events: |
@byrion Thanks, but that patch emits a connect_failed under a very specific case (setting a timeout after injecting a script element to detect script loading failures). It doesn't solve the problem, which is that the *_failed events don't get emitted in the client at all under Node. The core of the problem is that something is wrong with the redoTransports code path: https://github.com/LearnBoost/socket.io-client/blob/master/lib/socket.js#L492 |
OK, so here is a bit more info - looking for the cause:
https://github.com/LearnBoost/socket.io-client/blob/master/lib/socket.js#L494 However, since failures that occur during handshakes cause an "error" event to be emitted rather than some more descriptive event (connect_failed would probably be a better choice), the cleanup never occurs, and neither are the "connect_failed" and "reconnect_failed" events emitted. In addition, even "error" events during the handshake are suppressed when the socket is reconnecting: https://github.com/LearnBoost/socket.io-client/blob/master/lib/socket.js#L159 So I think the fixes would include:
Having a mandatory "go through all the failed transports again" phase makes the time spent in the disconnected state without being able to apply custom recovery options even longer than necessary. If reconnect_failed happens, that should mean that the developer should do whatever they have planned as the fallback. So I would remove the redoTransports code path and just emit a reconnect_failed directly + make handshakes emit connect_failed events. Core devs, any guidance on this? |
I've found similar results from my testing. To get around the reconnect_failed message not being sent, I instead use the reconnecting event and look for the last attempt and throw an error message on the screen so the user knows push updates won't occur anymore. I also throw the same message up on an error. Between the both it seems to reliably inform the user of the status of the connection. |
I am experiencing the same issue with: reconnect_failed [UPDATE] So it requires a reconnection limit that matches the max reconnection attempts in ms. Another example: I did run into an issue with the exponential back off, but I will open a new issue for that. [UPDATE 2] Within the reconnect prototype, the maybeReconnect method contains this logic: if (self.reconnectionAttempts++ >= maxAttempts) { After the final reconnection attempt, its caught in the if(!self.redoTransports) statement. |
Reading @mixu post above, he makes a valid point about there not being a timeout in the redoTransport logic. So I am going to fork and add: self.reconnectionTimer = setTimeout(maybeReconnect, 1000); to the end of that logic. It adds an additional second to allow whatever that logic is attempting to do and then executes maybeReconnect again with self.redoTransports set to true. This fork, coupled with my other pull request: #328 fixes both issues I had previously. |
As part of my tests under 0.6.17, I used to take down the socket.io server and bring it back up when the client noticed it was disconnected.
Additionally, I used to test specifying invalid connection port information to the client and use the connect_failed event to fall back to the correct port. This is basically because some corporate clients can't access the normal port used for socket.io, since it's not 443 or 80 and need to fall back to port 443 (which is a polling-only fallback through an Nginx rule).
However, I cannot get the client to emit connect_failed or reconnect_failed in my tests under Node - which breaks both of the above since I need those events in the client to respond correctly to server failure and connect failure due to firewall blocking the connection.
The test code consists of a runner - a separate process for the socket.io server, since we don't care why the server is inaccessible (and doing client disconnects() sends back "booted" which prevents reconnects) - sio.runner.js:
And then the test itself:
Now, if you run that code, you get:
Note that you need to wait quite long for the client heartbeat to fail.
I would expect to get a "connect_failed" or "reconnect_failed" event to be emitted before giving up, but can't seem to get one.
The text was updated successfully, but these errors were encountered: