如何通过 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?的主要内容,如果未能解决你的问题,请参考以下文章
/socket.io/socket.io.js 中不提供 Socket.io