【问题标题】:Send specific message to specific socket.id with socket.io使用 socket.io 将特定消息发送到特定的 socket.id
【发布时间】:2019-01-07 14:36:52
【问题描述】:

我在为我的问题找到正确答案时遇到了问题。如果我可以说,我希望像 Telegram 这样的每个用户都有私人消息传递。或者像 StackOverflow 上的通知一样,套接字事件仅发送给特定用户。

io.on('connection', function (socket) {
  // this will be only sent to a user that just connected
  socket.emit('news', { hello: 'world' });
});

但是如何发送带有自定义 id 的特定消息?

这是我的 socket.js

const socketio = require('socket.io')
const { redis, saveUser } = require('./redis')

module.exports.listen = function(app){
io = socketio.listen(app)

  io.on('connection', socket => {
    console.log('connected user', socket.id)

  socket.on('join', (payload) => {
    redis.get(payload.email (err, socket_id) => {
      socket.broadcast.to(socket_id).emit('join', `Hello ${payload.whoChat.name} Chat you`)
      })
    })      
  })

return io
}

但这不会向我的用户发送任何内容,如果使用房间,它将直接发送到房间,当我查找文档时,io.to()io.broadcast.to() 可以与套接字房间一起使用。

所以我决定把它简单化,但现在我的 server.js 是错误的。

io.on('connection', function (socket) {
  socket.on('join', payload => {
   socket.emit('join', payload)
})

在客户端

socket.on('join', (payload) => { 
    // Compare data from socket with local data if match then push the message 
    // to users who recieve
    if ( payload.userId === localData.userId ) {
        this.message.push(payload.message)
    }
})

但实际上我将它发送给所有用户......如何正确和正确地做到这一点?以及如何保存用户socket.id?由于 socket.id 是随机生成的,当用户断开连接时,如何将其保存以供将来的请求使用?

【问题讨论】:

    标签: node.js websocket socket.io


    【解决方案1】:

    你需要维护一个_socket_id/user_id_的map

    服务器

    const sessionsMap = {};
    
    io.on('connection', (socket) => {
      socket.emit('askForUserId');
    
      socket.on('userIdReceived', (userId) => {
        sessionsMap[userId] = socket.id;
      });
    
      socket.on('send', (message) => {
        const receiverId = sessionsMap[message.receiverId];
        const messageData = message.data;
        socket.broadcast.to(receiverId).emit('my message', messageData);
      });
    });
    

    客户

    const userId = 'FOO';
    
    io.on('askForUserId', () => {
      io.emit(userId);
    });
    
    io.on('send', (message) => {
      console.log('You received a message');
      console.log(message.data);
    });
    

    注意

    请务必查看Socket.IO cheatsheet,它涵盖了很多命令和用例。

    【讨论】:

    • 那么我从数据库中获得的会话映射?或者会话。用户连接时应该永远保存的东西?是否需要使用房间和命名空间?编辑你的答案,sessionsMap[userId] = sessionId ;socketId 来自哪里?
    • 编辑了答案。 socketId 实际上是 socket.id(错字)。您不需要需要sessions map 存储在数据库中。如您所见,我使用了一个基本的 javascript 对象const sessionsMap = {};。尽管您也可以将其存储在数据库中,但如果您要走这条路,请考虑使用Redis,因为它更快(在内存数据库中)
    • sessionId这个变量有什么用?
    • 是的,你也不需要那个变量,我将socketIdsocket.idsessionId 混合在一起。它们都是一样的,我编辑了答案以反映这一点
    • 是的,这个解决方案就像魅力一样,谢谢。我对.rooms 和命名空间做更多的研究也许会有所帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-08
    • 2017-12-03
    • 2021-04-10
    • 2014-08-14
    • 2014-07-25
    • 2014-02-05
    相关资源
    最近更新 更多