使用 Socket.io 的通知 - 如何发送给特定的用户/收件人?

Posted

技术标签:

【中文标题】使用 Socket.io 的通知 - 如何发送给特定的用户/收件人?【英文标题】:Notifications with Socket.io - how to emit to a specific user/recipient? 【发布时间】:2020-11-18 23:03:33 【问题描述】:

我想实现一个简单的通知系统。当user1 点赞user2 的帖子时,user2 应该会收到来自user1 的实时通知。

这是客户端功能(Redux 操作)的一部分,其中有人喜欢一个帖子:

.then(() => 
  const socket = require("socket.io-client")(
    "http://localhost:5000"
  );
  socket.emit("like", user, post);
);

这是在user1 喜欢user2 的帖子后创建通知的服务器套接字函数:

io.on("connection", (socket) => 
    socket.on("like", async (user, post) => 
        if (!post.post.likedBy.includes(user.user._id)) 
            const Notification = require("./models/Notification");

            let newNotification = new Notification(
                notification: `$user.user.username liked your post!`,
                sender: user.user._id,
                recipient: post.post.by._id,
                read: false,
            );

            await newNotification.save();

            io.emit("notification");
        
    );
);

这是创建通知后的客户端函数:

socket.on("notification", () => 
        console.log("liked");
);

现在的问题是console.log('liked') 出现在user1user2 上。如何仅向接收通知的用户发出? socket.io 如何找到接收到来自user1 的通知的特定user2

【问题讨论】:

不仅是user1和user2,所有用户都会在这里收到通知 是的,这就是我要解决的问题。我只希望recipient 收到通知。 我下面的答案有效吗? 我会在今天晚些时候尝试并回复您,谢谢! :) 【参考方案1】:

您应该像这样存储所有用户的列表(数组或对象):

(请注意,当用户connectsleaves 套接字服务器时,列表必须更新)

// an example of structure in order to store the users
const users = [
  
    id: 1,
    socket: socket
  ,
  // ...
];

然后你可以定位帖子所有者并向他发送这样的通知:

// assuming the the 'post' object contains the id of the owner
const user = users.find(user => user.id == post.user.id);
// (or depending of the storage structure) 
// const user = users[post.user.id]
user.socket.emit('notification');

这里是一个例子:

const withObject = ;
const withArray = [];

io.on('connection', socket => 
  const user =  socket : socket ;
  socket.on('data', id => 
    // here you do as you want, if you want to store just their socket or another data, in this example I store their id and socket
    user.id = id;
    withObject[id] = user;
    withArray[id] = user;
    // or withArray.push(user);
  );

  socket.on('disconnect', () => 
    delete withObject[user.id];
    delete withArray[user.id];
    // or let index = users.indexOf(user);
    // if(index !=== -1) users.splice(index, 1);

  );
);

有很多方法可以实现我要解释的内容,但主要思想是将套接字与其他索引(例如用户 ID)链接起来,以便稍后在代码中检索它。

【讨论】:

所有users都在MongoDB数据库中。如何将它们中的每一个存储在 socket 中? 您可以将他们的套接字存储在服​​务器上的变量中。当用户连接到套接字服务器时,您将他作为对象(他的 id 和他的套接字)添加到全局数组中。当他断开连接时,您将他从全局数组中移除。 您能帮忙将它们添加到套接字服务器吗?我看到有一个数组,但是如何自动将它们添加到其中? 在“连接”事件中,您可以将套接字保存在数组(或对象)中。为了存储 id,您必须发出另一个事件,例如“数据”事件。我在答案中添加代码 感谢您的耐心等待。那么我需要发送到接收者的socket.id 吗? user.socket.emit('notification'); 没有任何反应

以上是关于使用 Socket.io 的通知 - 如何发送给特定的用户/收件人?的主要内容,如果未能解决你的问题,请参考以下文章

Node js socket io chat 发送消息通知

如何使用 Express、AngularJS、Socket.io 广播和获取通知?

如何使用nodejs socket.io向特定房间中的用户发送打字警报和消息

如何使用 socket.io 实现长轮询?

使用 socket.io 更新使用通知

在节点 js 中推送通知