How to do RPC over socket.io?

梦想与她 提交于 2019-12-01 03:24:36

问题


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?


回答1:


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 );
     });
 }



回答2:


With socket.io you can send and receive acknowledgements via callbacks.

See this: http://socket.io/docs/#sending-and-getting-data-(acknowledgements)



来源:https://stackoverflow.com/questions/23962196/how-to-do-rpc-over-socket-io

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!