socket.io: 客户端发出的回调永远不会触发

11

只是为了概念验证而深入研究socket.io,到目前为止一切都运作得很好,除了我无法在客户端使我的emit回调函数工作。我肯定在这里错过了一些愚蠢的东西,但目前文档并不完美。服务器成功地接收到“getSomeData”事件,没有任何错误。

根据我从客户端socket.io源码中了解到的信息,它检查emit的最后一个参数是否为函数,并始终将其用作回调,但对我来说,要深入调试比较困难。

我觉得我一定在这里缺少了一些核心概念...这难道不是this.send(..)应该做的吗?我在示例应用程序中只找到了1个用法,并且没有可用于该事件发射的客户端代码。

更新:只是为了明确,我实际上是有意在客户端发射事件的。这样做的目的是看看是否可以使用socket.io允许客户端在请求时拉取数据,以及接收推送。

服务器:

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

io.sockets.on('connection', function (socket) {
    socket.on("getSomeData", function() {
        this.send({data: "some random data"});
    });
});

客户端: (console.log从未发生)

<script type="text/javascript" src="http://localhost/socket.io/socket.io.js"></script>
<script type="text/javascript">
  var socket = io.connect('http://localhost');
  socket.emit("getSomeData", function(data) {
      console.log(data);
  });
</script>
3个回答

23

看起来你的逻辑有些混乱了,请尝试...

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

io.sockets.on('connection', function (socket) {
    socket.emit("getSomeData",{data: "some random data"});
});

并且客户端代码也应该忽略这个字段。如果您的API需要在响应中包含某些元数据,例如版本信息或分页信息,���最好将它们放在响应头中。

<script src="http://localhost/socket.io/socket.io.js"></script>
<script>
  var socket = io.connect('http://localhost');
  socket.on("getSomeData", function(data) {
      console.log(data);
  });
</script>

编辑:

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

io.sockets.on('connection', function (socket) {
    socket.on("getSomeData", function(name,fn) {
        fn({data: "some random data"});
    });
});

客户端

<script src="http://localhost/socket.io/socket.io.js"></script>
<script>
  var socket = io.connect('http://localhost');
  socket.emit("getSomeData", function(data) {
      console.log(data);
  });
</script>

在这种情况下,我真的想知道是否可以使用socket.io允许客户端按需拉取数据,而不仅仅是允许服务器推送。虽然您修改后的代码可以正常工作,但它实现了概念上不同的东西。 - jdc0589
我只会创建一个getset的等效函数。我不会过度复杂化任何事情。使用emit来调用一个函数,使用on来设置它。 - Lime
那是我的最后一招。但我觉得调用this.send应该做这种事情,而且这是一个更清晰的解决方案。只需要弄清楚它是否被正确使用或者我做错了什么。 - jdc0589
我更新了我的回答。我重新阅读了你的帖子并编辑过,现在我觉得我明白了你的意思。 - Lime

6
在Liam William的答案中,我发现在客户端emit时需要将回调(或确认函数)作为第三个参数发送:
客户端:
<script src="http://localhost/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost');
socket.emit("getSomeData", null, function(data) {
    console.log(data);
});


2
这解决了我的问题。在不提供函数时悄悄失败是真的讨厌的行为,我个人认为。 - Callum Rogers

1

您可以使用回调函数,但需要稍微修改一下:


服务器: (app.js)

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

io.on('connection', function (socket) {
// please note that server will take 2 data entries as function parameter below
  socket.on('ferret', function (name, fn) {
    fn('woot');
  });
});

客户端(index.html)

var socket = io(); // TIP: io() with no args does auto-discovery
socket.on('connect', function () {
socket.emit('ferret', 'tobi', function (data) {
    console.log(data); // data will be 'woot'
});
});

实际上,Socket.IO 也提到了这一点; 发送和获取数据(确认)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接