如何通过 socket.io 进行 RPC?

Posted

技术标签:

【中文标题】如何通过 socket.io 进行 RPC?【英文标题】:How to do RPC over socket.io? 【发布时间】:2014-07-20 15:53:27 【问题描述】:

假设我们有一个简单的回显服务器(在第一次请求时调整为更长):

var waiting = 8000;
io.on('connection', function(socket)   
    socket.on('doEcho', function (data) 
        setTimeout( function () 
            socket.emit('echoDone', data);
        , waiting);
        waiting = 1;
    );
);

然后说一个index.html 客户端脚本:

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

其中askEcho 是以下错误函数,伪装成 RPC 存根:

function askEcho (text, fun) 
     socket.emit('doEcho', text);
     socket.on('echoDone', function (data) 
         fun ( data );
     );
  

显然我得到的是以下混乱

接听 11111 22222 回答 22222 22222 回答 11111 11111 接听 22222 11111

因为我为同一个事件安装了两个监听器。这可以很容易地解决, 但我不清楚如何在客户端正确订购响应, 在服务器端没有帮助(编程更多)。

这一切似乎有点太多的负担。 不能把askEcho 函数编码得恰到好处吗?

【问题讨论】:

【参考方案1】:

实际上,有一个简单的技巧:使用计数器来区分答案,并在完成后删除回调(最好使用once 而不是on)。这只会在服务器端和客户端造成微小的变化。

让我们展示一下:

回显服务器是(现在没有任何延迟超时):

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

在客户端 (index.html) 中,用户代码仍然如所愿:

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

这是与服务器端协同工作的存根askEcho

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

【讨论】:

如果你懒得自己实现,我有这个小库:github.com/capaj/socket.io-rpc 有些情况下回调永远不会被移除。处理它们很痛苦(超时、断开连接时的清理等),所以我不会称这是一个简单的技巧。【参考方案2】:

使用 socket.io,您可以通过回调发送和接收确认。

看到这个:http://socket.io/docs/#sending-and-getting-data-(acknowledgements)

【讨论】:

以上是关于如何通过 socket.io 进行 RPC?的主要内容,如果未能解决你的问题,请参考以下文章

io() 函数前端——socket.io

/socket.io/socket.io.js 中不提供 Socket.io

怎样通过RPC命令实现区块链的查询

Node.js 和 socket.io 的混淆

多个侦听器和 removeListener 删除所有内容 Socket.io

socket.io 和 node.js 400 错误请求