Tell server that user is no more on internet - node.js

I am new to node.js and trying to develop group chat using node.js and socket.io. I am able to do group chat also able to manage data in the system.
Now, the problem with me is with offline users i.e not connected to internet.
I am having connection stream of this user and as if I do receiverUserSocket.emit("sendMsg",data) there is no way to verify if this user received message or not.
Yes, there is an event .on("disconnect") but I am getting delay of approx 30 - 40 seconds.
Is there any way we can identify that the user to whom we want to send message is online or offline.

The best way is to use socket.io heartbeats - assuming you're using socket.io.
Heartbeats and the problem with detecting a terminated connection are well explained here:
Advantage/disadvantage of using socketio heartbeats
Keep in mind that you can control heartbeat timeout values (thus forcing the disconnect event to appear much faster), as explained here:
Controlling the heartbeat timeout from the client in socket.io
But that might put much more strain on your server.

Related

Socket.io handle online/offline status

I've a real time chat application i've implemented it using socket.io, nodejs and angularJS but i'm having issues while handling the online/offline status. I'm not clear on how to know when the user is online or offline. What i thought is hitting a api in every 3 seconds and update the online/offline status in the database but i don't feel it's a good way so is there any better way to handle it?
Thanks in advance!
Here is the link to my backend code.
DesktopChat-Backend
You don't need to hit every 3 seconds , socket.io do this automatically, so you have just to handle it inside on. ('connection') and on.('disconnect'), so you get the user connected or disconnected then you broadcast the information to the clients, and update their status.
Look at this example :
Showing online users using Nodejs and Socket.io and angular js
One-to-One-Chat-using-Node.js-Socket-IO-Library
you can make map, where your userId will be associated with all socket.io client ids for this user. Then you can just look into this map, if specific user has some open connections.

NodeJS Synchronize clients

I'm using socket.io and nodejs,
I have a server and I use it as my nodeJS server. What I'm trying to do is moving clients according to messages sent as client -> server -> clients
For example; client1 sending a message "MOVE-RIGHT" to server. Server redirecting this message to all clients LIKE "MOVE-RIGHT-CLIENT1" and according to this message, all clients starting to move client1 to the right direction.
The problem is, all clients may have different latency according to their network status. For example, if server->client1 communication happens in 50 ms, server->client2 communication may happen in 250 ms. Therefore, client1 does this job nearly 200 ms earlier. So we can say that these two movements are not synchronized because one of them happens earlier than other ones.
As you know latency between clients and server may be different for each clients, and also it can be different for each message for the same client.
My question is, Which method should I use to synchronize these clients, to do their jobs at the same time. Is there any feature of socket.io or nodejs about this? What would you recommend for me?

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.

Does sockets.io emit sometimes fail?

I have a web based multiplayer game. It happens from time to time that someone is kicked out because server did not get expected message from client. It seems from my logs that client did not disconnect, just did not send message or server did not receive it. My question here is "Does this things happen normally from time to time?" Should i use some kind of callback mechanism to ensure message is delivered and if not send it again or is there some issue that i am not aware?
socket.io already provides ACKs and message ID tracking, on top of TCP.
Also, socket.io uses pings to check the connection. So, if you say that the client is not disconnected, and the server tells that the client is not disconnected, then the connection is still there.
The problem must be situated elsewhere.
Are you sure there is not a bug in either part of the implementation? Showing some code snippets could help, as well as the environment you are using.

What is the best way to keep track of which users are online in nodejs?

So I am developing (more playing around with) a realtime game in node.js, I am also using Redis and Sockets.io. I have players create a lobby and join it (kind of like a pre-game chat room, where you can talk to players and select game settings) . The client is written in HTML/CSS/JS, Anyway I want to be able to tell when players disconnect from the lobby, to update the number of players joined on the interface (and joined player names).
Two options I have thought about are:
Using redis' key value timeout feature, to remove a particular field if it is not updated in x amount of time. I would then have the host check the existance of this field to check for DC's. I do wonder if this is highly inefficient, as many users potentially will be playing, so will it be bad to have many timeout values in redis and also many other users polling these fields.
I could use the sockets.io on('disconnect', ..) to update the field. However I am not sure if this event will fire if for example a users pc freezes?
Anyway I am open to any other ideas also!
Socket.io have a 'heartbeat' to check connection still alive. Default heartbeat timeout is 15s. You can read more about configuring it in this wiki. If heartbeat fails (user pc freezes) then socket.io will emit 'disconnect' event.
Socket.io should suffice. You can configure it to use heartbeats to ping the socket and check its health. If a user's computer freezes it will, in effect, not be able to respond to these heartbeats, causing it to force a disconnect.
To test this you could set up your Socket.io to use heartbeats, then connect via a browser onn a different computer. While in the browser past into the console an infinite loop. Causing it to simulate a freeze.

Resources