Node.js - Socket.io io.emit() 什么都不做

use*_*369 2 javascript node.js socket.io

我的 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);
});
Run Code Online (Sandbox Code Playgroud)

客户:

<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>
Run Code Online (Sandbox Code Playgroud)

如您所见,在客户端 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); 
Run Code Online (Sandbox Code Playgroud)

那也行不通。IE 你不能用那种方法让套接字加入一个房间。

Vit*_*tik 5

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

通过编写,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");
Run Code Online (Sandbox Code Playgroud)

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

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

console.log(io.sockets.name) // '/'
console.log(io.of('/projects/test_cases').name) // '/projects/test_cases'
Run Code Online (Sandbox Code Playgroud)

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

io.of('/projects/test_cases').emit("test_case_changed", "test1");
Run Code Online (Sandbox Code Playgroud)

UPD: 至于问题的第二部分,您可能想知道这join是一个异步操作。这就是为什么room1socket.rooms正确的下一行代码。当插座在房间内时,您可能会使用以下几行收到通知:

socket.join("room1", function(err){
    console.log("After join: ", socket.rooms);
});
Run Code Online (Sandbox Code Playgroud)

  • @ecarrizo 从来没有说过开发人员很烂,他们显然非常有才华,只是文档很烂。如果在线提供每个功能的功能描述,我就永远不会遇到这个问题。我遇到的问题是我不知道 io.emit 只发送到 '/' 命名空间,并且 socket.rooms 没有列出该套接字连接到的房间。如果有文档解释这些函数的作用,我就不会遇到这些问题。那里的文档只是基本教程,没有提供这些细节。 (2认同)