如何使用 socket.io 从控制器函数发出?

how to emit from a controller function with socket.io?

我正在构建我的第一个 MERN 应用程序 [留言板] 并尝试使用 socket.io 添加邮件通知。

到目前为止我在 server.js:

const io = socketio(expressServer);
const connectedUsers = {};

io.on('connection', (socket) => {
  socket.emit('messageFromServer', { data: 'Welcome to the server' });
  socket.on('messageToServer', (dataFromClient) => {
    connectedUsers[dataFromClient.username] = socket;
  });
});

要从我的控制器文件发出,我需要 io 对象还是只需要套接字,我如何与控制器文件共享 it/them?

非常感谢所有帮助!

为您的用户跟踪设置一个外部文件connectedUsers.js以避免circular dependencies

const connectedUsers = {}

module.exports = { connectedUsers }

服务器设置:

const { connectedUsers } = require('./connectedUsers')

io.on('connection', (socket) => {
  socket.on('messageToServer', (dataFromClient) => {
    connectedUsers[dataFromClient.username] = socket;
  });
});

下一个问题是将 io 实例获取到 router/controller。为此,我通常在服务器设置中

app.io = io

然后在 router/controller 中,您可以从 req 对象访问 io 实例:

const { connectedUsers } = require('./connectedUsers')

router.post('/message', function(req,res){
  if ( connectedUsers[req.body.username] && connectedUsers[req.body.username].id) {
     const id = connectedUsers[req.body.username].id
     req.app.io.to(id).emit({ msg: 'blah' })
  }
})

上面的 if 检查是一个代码示例,在您使用 connectedUsers 的任何地方都会弹出。简单的对象通常会变成单例 class ConnectedUsers {} 实例,因此可以附加通用代码,而不是散落在整个控制器中。