0

I am building a simple chat. I am using the websocket lib socket.io because it has a great server/client implementation.

My client is on mobile and therefore has a very unstable network connection. I have read something about acknowledgment functions which could be passed with an emit, to execute code once the socket "transaction" is done. But building an error handling on top of that would be very uggly.

I have also read about the .on('error' implementation that catches errors.

The problem here is: how do I seperate between an unsuccessfuly sent message (.emit) and a temporarily lost socketconnection. I dont care about losing the socketconnection because i set it up to reconnect once its lost.

I hope my situation got clear. Thanks in advance.

EDIT:

What I am looking for is something like this on the clientside:

socket.on('error', function(data){
   alert(data.emitData.msg+' could not be sent: '+data.emitID);
});

I am going to start taking a closer look at the API myself in the meantime

Max Bumaye
  • 1,017
  • 10
  • 17

1 Answers1

2

Message acknowledgement is covered here in the socket.io docs. Here's the relevant part of that docs:

Sometimes, you might want to get a callback when the client confirmed the message reception.

To do this, simply pass a function as the last parameter of .send or .emit. What’s more, when you use .emit, the acknowledgement is done by you, which means you can also pass data along:

Server (app.js)

var io = require('socket.io').listen(80);

io.sockets.on('connection', function (socket) {
  socket.on('ferret', function (name, fn) {
    fn('woot');
  });
});

Client (index.html)

<script>
  var socket = io(); // TIP: io() with no args does auto-discovery
  socket.on('connect', function () { // TIP: you can avoid listening on `connect` and listen on events directly too!
    socket.emit('ferret', 'tobi', function (data) {
      console.log(data); // data will be 'woot'
    });
  });
</script>

And, another example shown here: Acknowledgment for socket.io custom event

Community
  • 1
  • 1
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • thanks for explaining acknoledgments in more detail - but how do you think this could help me find out what message actually was not delivered to the server. No connection to the server = no acknowlogment cb – Max Bumaye Dec 09 '14 at 09:33
  • @MaxBumaye - what I described is the acknowledgement confirmation. If the packet is not delivered, you will get an error on the websocket and you can listen for errors by listening for the `error` message. TCP is a reliable protocol so you will either get a confirmation or an error - one or the other. – jfriend00 Dec 09 '14 at 22:09
  • Oh, okay, do I understand this correctly that I dont actually need the acknowledgement func to do anything? – Max Bumaye Dec 09 '14 at 22:11
  • Pass an empty acknowledgement function that emits "error" if it doesnt get called? – Max Bumaye Dec 09 '14 at 22:12
  • @MaxBumaye - if you only want errors, then just listen for the `error` message and process that. No need for an acknowledgement function if you don't want acknowledgement. The protocol is reliable either way. It will either deliver the message to the server or give you an error. – jfriend00 Dec 09 '14 at 22:14
  • Okay so just to get this right: If I catch the error .on('error'... how do i match it to the specific emit I made... to be more precise: what happens if I emit 5 messages and 1 doesnt get delivered, how am I aware of this 1? – Max Bumaye Dec 09 '14 at 22:19
  • @MaxBumaye - I don't know the details. I would assume that the error object that comes with the error message has info in it about which message send failed, but I can't find anything in the "thin" socket.io documentation that offers any explanation of that. You'd probably have to cause an error and test to see. Because TCP is reliable and socket.io automatically reconnects, you are unlikely to get a spurious single error. If you get an error, it's probably the case that either the server is down or the browser's internet path to the server is down or the client is hosed. – jfriend00 Dec 09 '14 at 22:26
  • @MaxBumaye - I should add that if a webSocket gets an error, it is immediately closed (by specification) so the webSocket will first generate an error message and then a close message. That doesn't necessarily help you know which message failed, but it does show you that this is an error condition is not just a one message error, it's usually a general transport or server failure. – jfriend00 Dec 09 '14 at 22:32
  • I think TCP protocol would try to process the emit several times but what happens if connection is lost in longer terms AND aditionally the user tries to emit a message. Maybe I should go with socket.isConnected or something simular instead? I just tried emitting during a lost connection -> the Error doesnt get caught. Probably the error is listening on the connection. Maybe I should wrap the emit Message into some kind of If(socket.isConnected) and prevent sending messages when disconnected ?? how do you like this advance? – Max Bumaye Dec 09 '14 at 22:33
  • @MaxBumaye - that's the kind of thing that if you really want robust error handling, you will have to simulate various failure cases and see how the underlying system behaves in order to code for it properly. The `socket.io` documentation is way too thin to know how it behaves in instances like this. If the system knows there is an error, then the socket will already be closed or in a retry state and you can either listen to those messages to know whenn it is doing that or query it's state. – jfriend00 Dec 09 '14 at 22:35
  • thanks for your help, things have become a lot clearer – Max Bumaye Dec 09 '14 at 22:40