Node.js error handling with socket.emit - javascript

I have some node.js client side code like this:
socket.emit('clickAccept', { myrecid: recid });
Server side node.js code gets it fine and all is well.
If I take the server down to simulate a server side outage, then click the button that fires this socket.emit on the client side, this happens:
Nothing really, I guess it might eventually time out
When I bring the server back up, the clicks end up being sent to the server and the server acts on them (TCP-like I Guess).
What I want to happen is for those socket.emit calls to die after a short timeout and not send when the server comes back up, it causes all sorts of confusion because if they click 3 times, nothing happens, then when/if the connection or server comes back up they get 3 reactions all at once.
Also, if they click and it times out because the server is down, I would like to show an error to the client user to let them know that basically the click didn't work and to try again.
I know how to act on and show an error if the socket goes down but I don't want to do this if they aren't trying to click something at that time. No sense is firing errors at the user because the socket went down briefly if they have no need to do anything at that moment.
So, to be clear, I only want to show an error if they click on the button and the socket between the client and server is down. AND... If they get an error, I want to kill that emit, not save it all up and fire it and all the other clicks when the server comes back up a few seconds later.
Thanks in advance and I hope that was at least reasonably clear.

The root of your issue is that socket.io attempts to buffer any data that it can't currently send to the server (because the connection to the server is disconnected) and when the server comes back up and the connection is restored, it then sends that data.
You can see the technical details for how this works here: socket.io stop re-emitting event after x seconds/first failed attempt to get a response
You have several implementation options:
If socket.io already knows the client is not connected to the server, then don't buffer the data (perhaps even give you back an error to show to your user).
When socket.io reconnects and there was data buffered while the connection was down, clear that data and throw it away so old data isn't sent on a reconnect.
Implement a timeout to do one of the above after some sort of timeout.
So, to be clear, I only want to show an error if they click on the button and the socket between the client and server is down. AND... If they get an error, I want to kill that emit, not save it all up and fire it and all the other clicks when the server comes back up a few seconds later.
Probably, the simplest way to do that is to implement a version of what is shown in the above referenced answer:
Socket.prototype.emitWhenConnected = function(msg, data) {
if (this.connected) {
this.emit(msg, data);
return null;
} else {
return new Error("not connected");
}
}
Then, switch your code from using .emit() to use .emitWhenConnected() and check the return value when using it. If the return value is null, then no error was detected. If the return value is not null, then there was an error.

Thanks for the other answers and help. I ended up solving this in a super simple way. See below:
if (socket.connected){
// Do your thing here
} else {
// Throw error here that tells the user they're internet is likely down
}
Hope this helps someone out there, it was a huge improvement in our code to make sure that user's are getting proper feedback when if they have brief network/internet outages.

Related

Check if socket.io server is online from client

I am trying to make a simple socket.io game. I have a login screen, where you enter your username and password, and then you click a big connect button and then you're in (if the client manages to connect to the server). I would like to have a status box on the login screen, so you can see if the server is up or down. I am wondering if there is some sort of ping function in socket.io. Otherwise, could you try to connect to the server (for example, I don't know what's good) 4 times. If it fails, it calls a function/sets a variable, whatever. If it succeeds it calls a function or something, then it disconnects. I have googled around a bit, but can't find anything. (By the way, sorry if this is really noobish, and there is a really apparent solution. I'm new to socket.io 😅) All help will be deeply appreciated!
Socket io has an event listener for this situation. Reconnecting event will fire when socket.io tries to connect but fails. Its a bit misleading cuz it won't fire on every reconnect just when the reconnect try fails.
socket.on('reconnecting', function reconnectCallback(tries) {
if (tries === 3) {
//handle your offline mode here
}
});
socket.on('connect', function connectCallback() {
//handle successful connection here then disconnect
socket.disconnect();
});

What does connect_timeout do/mean in Socket.IO 1.0.6?

I'm trying to find the definition of connect_timeout, when is it fired, what's the use for it?
Reading here : http://socket.io/docs/client-api/#manager(url:string,-opts:object)
Right now I have an app I tried to run without turning on the server, and it tries to connect and the event "Reconnecting" is fired for 4 attempts, one every 2 seconds. Then it says "Failed Reconnecting" when it hits the 4 attempt mark and fires the event "reconnect_failed".
I haven't been able to hit the connect_timeout event. How do I do that? When does it happen?
I was hoping Socket.IO had some sort of function of "CONNECTING" and then if it failed it would continue attempting "CONNECTING" and if that failed it would say "CONNECTION FAILED" and if it connected successfully at some point, it would then call "RECONNECTING" instead and if that failed after a certain amount of attempts it would say "RECONNECTING FAILED". Is that something that has to be programmed by me? I haven't seen it built in.
Connection timeout is when a client is connected to the server and it takes too long for a response to be received, causing the client to disconnect because it has stopped receiving anything from the server. This can be caused by faulty internet or if the client loses connection to the server (i.e. the clients internet becomes disconnected). This is true for most server based communications and is likely the same for socket.io.

Trigger Event On Server Shutdown (NodeJS)

As we all know, when you update a nodejs file and upload it to your server, it needs a restart to be applied -- but if you're using something like nodemon where it automatically restarts your server, your clients that are logged in would need to refresh the screen.
So I was wondering, is there a way I could trigger a "logout" when my server goes down/is restarted so that at the minimum it just refreshes the clients so they know what's happened?
As it stands they'll broadcast undefined errors because theyre session has been lost?
I tried to validate using a function I have called authenticate
function authenticate(req,res,next) {
if (!req.session.loggedIn) {
fs.readFile('./html/login.html', "utf8", function(err, html) {
res.send(html);
});
} else next();
}
and here's how I call the function:
app.io.route('move', authenticate, function(req) {
But my server crashes because the parameters are undefined at that point.
Basically think of it like an onbeforeunload event but instead of the browser, the server.
The approach I would take is have something like Socket.IO notify all connected clients that your server is performing a restart, this restart notice, once received, would cause the client to disconnect the socket and poll for the server to come back up. Once it's back up, you can do a hard or soft refresh.
Server Server
SIGINT/Exit received --> io.broadcast("server:restart") --
Client Client
-> receive "server:restart" --> disconnect socket, poll for server back up --
Client
-> load refreshed data
You can capture some signal events like shown here and based on some information here you can use the "exit" event.
process.on("exit", function() {
app.io.sockets.emit("server:shutdown");
});
This will only work if the emit process is syncrhonous (and it looks like it may be). That means you can't get a callback you can only broadcast the message and let the client do the rest.
If you want to "hard refresh" you can poll a "heartbeat" route that just returns if the server is good (and running, obviously) and then do a location.reload() call. For a soft refresh, ping a route that returns new page contents and then page swap ($("body").html(response)).

Is there anyway in flex to get the status of server?

we have an application where button click in flex side restarts the server and makes the client logged out. once after logout, If user logs in it gives error since the server is not up by the time. In our scenario the server takes time to restart because of the stuff(like back up). I want the user to be notified of the webserver status if he tries to log in.
is there any way to monitor the status of server in Flex side. or Will javascript help in finding whether the server is up or not?.
Also I tried redirecting to html page using external interface but I am not sure how to automatically redirect it again to the swf file when the server becomes active.the server downtime is not known(may be 2 or 5 or 10 minutes.)
So what would be the best approach.Any help would be of greatly appreciated.
Using URLLoader you can try to download a file on the server and listen to ioError or httpStatus.
private var testLoader:URLLoader;
private var testRequest:URLRequest;
...
testRequest = new URLRequest("http://server/testFile");
testLoader = new URLLoader(request);
testLoader.addEventListener(HTTPStatusEvent.HTTP_STATUS, onStatus);
private function onStatus(HTTPStatusEvent:event):void
{
//test the status, if the server is up, reconnect, else...
testLoader.load(testRequest);
}
Interesting problem. When you mean restart, do you mean just a specific service like Apache or like an actual reboot of the server? I ask because it would mean different scenarios. I'm not exactly sure what you're doing, but I'll assume that you're rebooting the server.
One of the problems here is that the client logs out, which is something we do not want. What I would do is have a second server which it's sole purpose would be authentication and giving status on the other server. This is a 'man in the middle' approach where this server doesn't log you out, but all calls are redirected to the other server.
From the Flex side, you can have it calls the 'man in the middle' to see what's the status. Depending on the technology you're using (polling vs pushing), you can get the data needed and show the user the status.

Handling server-side aborted long-poll/comet updates in jquery

I have an application which uses an open JQuery Ajax connection to do long-polling/comet handling of updates.
Sometimes the browser and the server lose this connection (server crashes, network problems, etc, etc).
I would like the client to detect that the update has crashed and inform the user to refresh the page.
It originally seemed that I had 2 options:
handle the 'error' condition in the JQuery ajax call
handle the 'complete' condition in the JQuery ajax call
On testing, however, it seems that neither of these conditions are triggered when the server aborts the query.
How can I get my client to understand that the server has gone away?
Isn't it possible to add a setInterval() function that runs every few seconds or minutes? That way you can trigger a script that checks whether the server is still up, and if not, reset the comet connection. (I don't know what you use for the long-polling exactly though, so I don't know if it's possible to reset that connection without a page reload. If not, you can still display a message to the user).
So something like this:
var check_server = setInterval(function() {
// run server-check-script...
// if (offline) { // reset }
}, 60000);

Categories

Resources