1

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.

robertklep
  • 198,204
  • 35
  • 394
  • 381
Fonewiz
  • 2,065
  • 3
  • 17
  • 17
  • 1
    It's clear what you _want_, but it's not clear what your specific problem is. Most, if not all, of your requirements have to be implemented manually: track the state of the connection, if the user clicks after the connection went down, show an error, debounce the clicks, etc. – robertklep Jul 08 '17 at 06:16

2 Answers2

2

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:

  1. 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).

  2. 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.

  3. 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.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • I love the sample code you provided, I am going to try that and see how it works for me then update here. Thanks! – Fonewiz Jul 08 '17 at 17:10
2

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.

Fonewiz
  • 2,065
  • 3
  • 17
  • 17