How to do RPC over socket.io?

callback, rpc, socket.io, socket.io-1.0

Solution

Actually, there is a simple trick: use a counter to differentiate between the answers, and remove the callback when done (even better use `once` instead of `on`). This only poses minor changes at server and client sides.

Let's show it:

The echo server is (now without any delaying timeout):

io.on('connection', function(socket){   
    socket.on('doEcho', function (callCounter, data) {    
        socket.emit('echoDone'+callCounter, data);
    });
});

In the client side (`index.html`) the user code is still the same, as desired:

askEcho ("11111", function (resp) {
    console.log("answer for 11111 " + resp);
});
askEcho ("22222", function (resp) {
    console.log("answer for 22222 " + resp);
});

and this is the stub `askEcho` that works properly in teamwork with the server side:

var callCounter = 0;
function askEcho (text, fun) {
     var localCallCounter = ++callCounter;
     socket.emit('doEcho', localCallCounter, text);
     socket.once('echoDone'+localCallCounter, function (data) {
         // not required: socket.removeListener ('echoDone'+localCallCounter);
         fun ( data );
     });
 }

Problem

Suppose we have a simple echo server (tuned to be longer on the first request): ``` var waiting = 8000; io.on('connection', function(socket){ socket.on('doEcho', function (data) { setTimeout( function () { socket.emit('echoDone', data); }, waiting); waiting = 1; }); }); ``` Then say a `index.html` client script does: ``` askEcho ("11111", function (resp) { console.log("answer for 11111 " + resp); }); askEcho ("22222", function (resp) { console.log("answer for 22222 " + resp); }); ``` where `askEcho` is the following buggy function, pretending to be an RPC stub: ``` function askEcho (text, fun) { socket.emit('doEcho', text); socket.on('echoDone', function (data) { fun ( data ); }); } ``` And obviously what I get is the following mess ``` answer for 11111 22222 answer for 22222 22222 answer for 11111 11111 answer for 22222 11111 ``` because I installed two listeners for the same event. This can be worked around easily, but I don't see that clear how to get the responses properly ordered at the client, without help (programming more) at the server side. This all seems a bit too much burden. Can't be the `askEcho` function coded right and easily?

Original source