首页 > 解决方案 > Socket.io 不会立即在新创建的房间中发送分组事件

问题描述

我在向新登录用户发送事件时遇到问题。我创建了一个“加入”事件,它将用户推送到一个数组,然后向一个房间内的所有用户发出新的操作“更新用户”。

const { addUser, getAllUsers } = require('./users');

const app = require('express')();
const http = require('http').Server(app);
const io = require('socket.io')(http);

const port = 3000;

const connected = {};
let connectedUsers = [];

io.sockets.on('connection', socket => {
  socket.on('join', ({ name }) => {
    const { error } = addUser({ id: socket.id, name }); // This method is pushing "User" to array. If error is occured, returning error.
    connected[name] = socket.id;

    socket.join('login-room');

    setTimeout(() => {
      io.in('login-room').emit('update-users', getAllUsers());
    }, 400);
  });

});

http.listen(port, () => {
  console.log('connected to port 3000');
});

如您所见,我在这里有“setTimeout”,使用此 setTimeout 一切正常。但如果我删除它 - 它就不起作用。似乎我们需要一些时间来将此套接字加入他的房间,然后发送一个事件。你有什么想法我该如何改进它?

标签: node.jsexpresssocket.io

解决方案


你说得对,加入房间需要一些时间。然而,setTimeout这是一个糟糕的解决方案,因为加入房间所需的时间是不可预测的。袜子也可能无法加入房间。

好消息是这socket.join()是一个异步方法,并且将回调作为第二个参数。所以像这样使用它:

socket.join('login-room', () => {
  io.in('login-room').emit('update-users', getAllUsers());
);

@l-faros 也是正确的,因为您的getAllUsers()方法可能是异步的,因此您将在那里遇到另一个同类问题。

恐怕你可能有一个 JS 知识空白,我建议通过阅读 JavaScript 异步性、回调、承诺和所有这些(谷歌是你的朋友)来填补。


推荐阅读