【问题标题】:Node.js - Socket.io io.emit() doing nothingNode.js - Socket.io io.emit() 什么都不做
【发布时间】:2015-08-23 12:14:58
【问题描述】:

我的 socket.io 应用程序出现问题,io.emit() 和 io.sockets.emit() 直接不起作用,它们什么也不做,也不返回错误。

我在这里提供了最简化的代码版本。

服务器:

var server = require('http').createServer();
var io = require('socket.io')(server);
var port = 8080;

io.use(function(socket, next){
  next();
});

io.of('/projects/test_cases').on('connection', function(socket){
  io.sockets.emit("test_case_changed", "test1"); // Doesn't do anything
  io.emit("test_case_changed", "test2"); // Doesn't do anything
  socket.emit("test_case_changed", "test3"); // Works
  io.to(socket.id).emit("test_case_changed", "test4"); // doesn't work

});

io.on('connection', function(socket){
  socket.on('disconnect', function(){

  });
});

server.listen(port, function(){
  console.log('listening on *:' + port);
  setTimeout(function(){
    io.sockets.emit("test_case_changed", "test"); // does nothing
    io.emit("test_case_changed", "test"); // does nothing
  }, 3000);
});

客户:

<script>
    var socket = io('http://localhost:8080/projects/test_cases');
    socket.on('error', function (reason){
      console.error('Unable to connect Socket.IO', reason);
    });
    socket.on('connect', function (){
      console.info('Connected');
    });
    socket.on("test_case_changed", function (data){
      console.log(data);
    });
</script>

如您所见,在客户端 test1、test2、test3 和 test4 应该都在客户端打印,但只有 test3 可以。

另外,如果在 on('connection') 方法中添加以下内容

  console.log("Pre join: ", socket.rooms); 
  socket.join("room1"); // Doesn't work
  console.log("After join: ", socket.rooms); 

这也不起作用。 IE 你不能用那个方法让socket加入一个房间。

【问题讨论】:

  • io.sockets 不是连接的套接字数组吗?
  • @agconti - 它是一个带有一些方法的对象。 socket.io 中一个非常令人困惑且大多未记录的接口。很棒的图书馆,糟糕的文档。
  • @agconti 是一个对象。该行没有返回任何未定义的方法错误,或者根本没有任何错误,而且我在其他人的实现中也看到过,所以我相信这是一个有效的调用。
  • @jfriend00 啊谢谢你把它弄明白了。
  • @jfriend00 它是如何安装 socket.io 中间件的。它仅在源代码中可用。

标签: javascript node.js socket.io


【解决方案1】:

这对我有用。一旦连接了另一个套接字,它就会向所有连接的套接字发送一条名为“事件”的消息。

我刚刚删除了未使用的代码,所以请先尝试这样做,然后从头开始。

另外,对我来说,文档工作还不错.. http://socket.io/docs/ 和特定于命名空间的 http://socket.io/docs/rooms-and-namespaces/

APP.JS

var server = require('http').createServer();
var io = require('socket.io')(server);
var port = 8080;

var nsp = io.of('/projects/test_cases');
nsp.on('connection', function(socket) {
    console.log('someone Connected!');
    nsp.emit('event', 'data');
});

server.listen(port, function(){});

index.html

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<script src="https://cdn.socket.io/socket.io-1.3.5.js"></script>
<script>
    var socket = io('http://localhost:8080/projects/test_cases');
    socket.on('error', function (reason){
        console.error('Unable to connect Socket.IO', reason);
    });
    socket.on('connect', function (){
        console.info('Connected');
    });
    socket.on("event", function (data){
        console.log(data);
    });
</script>
</body>
</html>

要测试它在 3 或 4 个选项卡中打开 index.html 文件,只需在其中一个上按刷新 5 或 6 次,然后检查控制台是否有其他选项卡.. 它应该记录“数据”几个次。

【讨论】:

    【解决方案2】:

    套接字属于某个命名空间。

    通过编写io.of('/projects/test_cases').on('connection', function(socket){});,您将所有连接的套接字放入“/projects/test_cases”命名空间。

    通过写作

     io.sockets.emit("test_case_changed", "test1");
     io.emit("test_case_changed", "test2");
    

    你发出一个不同于“/projects/test_cases”的默认命名空间“/”

    你可以很容易地看到使用的命名空间:

    console.log(io.sockets.name) // '/'
    console.log(io.of('/projects/test_cases').name) // '/projects/test_cases'
    

    您可能需要明确指定套接字的命名空间以向其发送消息

    io.of('/projects/test_cases').emit("test_case_changed", "test1");
    

    统一更新: 至于问题的第二部分,您可能想知道join 是一个异步操作。这就是为什么room1 不在socket.rooms 的下一行代码中的原因。 当套接字在房间中时,您可能会收到通知,使用以下行:

    socket.join("room1", function(err){
        console.log("After join: ", socket.rooms);
    });
    

    【讨论】:

    • 好吧,这解决了我问题的第 1 部分。我假设 io.emit 广播到所有命名空间。你觉得第二部分怎么样? socket.join() 在哪里不起作用?
    • 没关系,socket.join() 确实有效,但 socket.rooms 不会改变。我假设列出了套接字的所有当前房间,但它不包括新房间。但是,执行nsp.to("room1").emit() 确实有效。感谢您的帮助!
    • @ecarrizo 从来没有说过开发人员很糟糕,他们显然很有才华,只是文档很糟糕。如果在线提供每个功能的功能描述,我永远不会遇到这个问题。我遇到的问题是我不知道 io.emit 只发送到“/”命名空间,并且 socket.rooms 没有列出该套接字连接到的房间。如果有文档解释了这些功能的作用,我就不会遇到问题。那里的文档只是基本教程,没有提供这些细节。
    猜你喜欢
    • 2021-02-20
    • 2021-01-17
    • 2017-09-11
    • 2019-02-21
    • 1970-01-01
    • 2019-03-08
    • 2016-12-24
    • 2017-04-18
    • 2011-08-03
    相关资源
    最近更新 更多