How to debug websocket client losing connection and reestablishing it - node.js

I'm using node.js, websockets/ws.
In my site sometimes a random client loses connection without losing connection to other internet stuff. Less then a second later they connect back, with a new socket. (There is a code that calls socket.onClose, which tries to reconnect back to server)
On the server side I can't see or log anything wrong. Everything looks like a normal disconnect, same as closing the browser tab.
I am guessing the reason is either socket related or client related but I don't know where to begin to debug this problem.
I got ping/pong responses with 60 second timer, this isn't it. The user usually loses connection while active.
How can I debug this problem and find the reason?
I keep all the session info, data, within the socket and that is why I do not want people to lose their connection.
Thanks

Related

How socket.io disconnect works?

Socket.IO timeout (disconnect) occurs if there are no activity present in the socket, but how is detected that are no activity? I dont find information about that. How works the detection process? For example:
If user closes the website tab, occurs disconnect?
There is any way user loses connection and disconnect will not be executed?
Is possible cache information informs that Im online even if I leave the website?
If you open your browser's developer tools in the network panel, you can filter your requests to ws requests (web socket requests), in there you can see your active web sockets connections. If you choose one connection, you can see the headers, the frames, the cookies and timing. If you choose the frames option you can see what's being sent and received, between your browser and your web socket server.
The next image will make it clear for you, it's chrome's developer tools:
Now in there you can see there are some numbers, basically your browser and your server are doing ping pong. You can read more about these numbers in this answer SocketIO Chrome Inspector Frames
This ping pong is what keeps the socket alive so we know that there are no timeouts. As for the disconnect and the connect I advise you to read more about the WebSockets API, in there you can see there are event listeners for onclose, onerror, onmessage and onopen.
So answering this question:
For example: If user closes the website tab, occurs disconnect? There
is any way user loses connection and disconnect will not be executed?
No, the onclose event will be fired, but even if any cosmic reason the onclose isn't fired you will eventually disconnect due to timeout.
As for your other question:
Is possible cache information informs that Im online even if I leave
the website?
Yes, that's not up to sockets, that's up to you and your implementation. You can keep a list of online users and only update that list from time to time, let's say 10 minutes. You can keep the online users lists and between the time you update your online users list, some of them are already disconnected.

how to detect connection failed in node js?

I use net.connect to make socket connection, I wonder how to detect it when a connection has failed?
It seems this doesn't work
//this will return a net.Socket and automatically connect
var client = net.connect({port:22000, host:'10.123.9.163'});
//doesn't trigger a error event even if connection fails
client.on('error', (err)=>{console.log('something wrong')});
//now an error event is emitted reasonably
client.write('hello');
when I run this piece of code, the connection should fail, and it indeed fails because when I write some data, an error occurs. But, I can not detect the connection failure. How can I do that?
=====Ready to close======
God damn it, I think I have just make a mistake. In fact the connection succeeded but due to some security strategy the server close the connection, I find out by doing a telnet. After trying other port which should definitely fail, the error event is emitted, everything go normal as expected. So, I am gonna close this question in case of misleading other people, and also thank you guys for helping me :)
The easiest and most portable way is to simply implement a 'ping-pong' check where both sides send some kind of 'ping' request every so often. If n outstanding ping requests go unanswered after some period of time, then consider the connection dead. This kind of algorithm is basically what OpenSSH uses for example (although it's not enabled by default).

Socket.io: correct way for the server to reconnect the client

I'm building MEAN application with socket.io. When page is just loaded, socket connection is established and kept live while user navigates to various pages, thanks to single-page nature of the app.
The user information is available in my socket connection thanks to passport.socketio.
However, when user logs in or out, I want the connection to be re-initialized, since otherwise socket will contain obsolete data about the user. Currently, I tried to implement it in this way: when user logs in / out, server disconnects this particular client's socket by calling socket.disconnect();.
On the client side, I listen for disconnect event, and try to re-establish the connection, like this:
_socket.on('disconnect', function(reason) {
_socket.connect();
});
Ok, now, when user logs out or in, server disconnects the client, this client connects back, and user information in the socket is up-to date. So far, so good.
But, consider different case when connection is broken: server is restarted. Previously, it "just worked": when I stop my server, connection is broken, but when I start server again, connection is automatically re-established. But after I've added my _socket.connect(); call, it doesn't work anymore: connection is still down until I refresh the page in the browser.
I've checked that when server calls disconnect();, the reason given to disconnect handler is: io server disconnect. And when server stops, the reason is: transport close.
Ok, then, I've implemented my disconnect handler as follows:
_socket.on('disconnect', function(reason) {
if (reason === 'transport close'){
// don't do anything special
} else {
_socket.connect();
}
});
Now it works. But, all of it seems as absolute dirty hack. At the very least, the reasons given (io server disconnect and transport close) seem to be just human-readable strings, so they might change in the future, and this will cause my code to stop working. And, well, there should be better way to do this; I must miss something essential, but unfortunately I can't find any good documentation on socket.io.
So, the question is: what is the correct way for the server to reconnect some particular client?
Additionally, if you have any recommendations on resources to learn about socket.io, I'd appreciate it very much as well.

socket.io disconnects clients when idle

I have a production app that uses socket.io (node.js back-end)to distribute messages to all the logged in clients. Many of my users are experiencing disconnections from the socket.io server. The normal use case for a client is to keep the web app open the entire working day. Most of the time on the app in a work day time is spent idle, but the app is still open - until the socket.io connection is lost and then the app kicks them out.
Is there any way I can make the connection more reliable so my users are not constantly losing their connection to the socket.io server?
It appears that all we can do here is give you some debugging advice so that you might learn more about what is causing the problem. So, here's a list of things to look into.
Make sure that socket.io is configured for automatic reconnect. In the latest versions of socket.io, auto-reconnect defaults to on, but you may need to verify that no piece of code is turning it off.
Make sure the client is not going to sleep such that all network connections will become inactive get disconnected.
In a working client (before it has disconnected), use the Chrome debugger, Network tab, webSockets sub-tab to verify that you can see regular ping messages going between client and server. You will have to open the debug window, get to the network tab and then refresh your web page with that debug window open to start to see the network activity. You should see a funky looking URL that has ?EIO=3&transport=websocket&sid=xxxxxxxxxxxx in it. Click on that. Then click on the "Frames" sub-tag. At that point, you can watch individual websocket packets being sent. You should see tiny packets with length 1 every once in a while (these are the ping and pong keep-alive packets). There's a sample screen shot below that shows what you're looking for. If you aren't seeing these keep-alive packets, then you need to resolve why they aren't there (likely some socket.io configuration or version issue).
Since you mentioned that you can reproduce the situation, one thing you want to know is how is the socket getting closed (client-end initiated or server-end initiated). One way to gather info on this is to install a network analyzer on your client so you can literally watch every packet that goes over the network to/from your client. There are many different analyzers and many are free. I personally have used Fiddler, but I regularly hear people talking about WireShark. What you want to see is exactly what happens on the network when the client loses its connection. Does the client decide to send a close socket packet? Does the client receive a close socket packet from someone? What happens on the network at the time the connection is lost.
webSocket network view in Chrome Debugger
The most likely cause is one end closing a WebSocket due to inactivity. This is commonly done by load balancers, but there may be other culprits. The fix for this is to simply send a message every so often (I use 30 seconds, but depending on the issue you may be able to go higher) to every client. This will prevent it from appearing to be inactive and thus getting closed.

How to check if socket still connected?

I have a page on which users connect to my node server with socket.io but I only allow them to have one open socket.io connection to the server (by passing along their account id when authorizing them and storing it in an array) and this works fine 99% of the time. The problem is that sometimes when users disconnect, the serverside disconnect event doesn't fire for some reason, so I can't clear their account from the array of clients, which ends up with them being locked out.
Is there a way for me to check if their old socket connection (which I have the ID of) is still active? (So if it isn't I can clear their old connection and let them connect again)
Make sure that heartbeats is set to true (the default). If the timeout lapses, disconnect should happen automatically. However, there was a bug report about heartbeats not working. Make sure you have the latest version of Socket.IO (I'm not sure the status of the bug).
If you still need help, you could send a ping to the old connection when the user tries to reconnect:
Emit a 'ping' from the server, and reply with 'pong' from the client if the connection is still alive. If the ping times out (after say, 20 seconds), drop the connection manually so the user can reconnect. You could use the ping to notify the original client that another client is trying to connect, and raise some UI to that effect.

Resources