使用Socket.io发送通知 - 如何向特定用户/接收者发出事件?

3
我希望实现一个简单的通知系统。当用户1点赞用户2的帖子时,用户2应该从用户1那里得到实时通知。
以下是客户端函数(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,所有用户都将在此处收到通知。 - Namysh
是的,这就是我想要解决的问题。我只希望“收件人”收到通知。 - David
我的下面回答有效吗? - Namysh
我今天稍后会尝试并回复你,谢谢! :) - David
1个回答

4
你应该像这样存储所有用户的列表(数组或对象):
(请注意,当用户连接或离开套接字服务器时,必须更新列表):
// 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)相关联,以便以后在代码中检索它。


所有的“用户”都在MongoDB数据库中。我该如何将它们存储在“socket”中? - David
你可以在服务器上将他们的套接字存储在变量中。当用户连接到套接字服务器时,您将其作为对象加入全局数组(包括其ID和套接字)。当他断开连接时,您从全局数组中将其删除。 - Namysh
感谢您的耐心等待。那么我需要向接收方的socket.id发出吗?使用user.socket.emit('notification');没有任何反应。 - David
我手动刷新应用程序后,它出现了某些原因无法发射。这是因为我没有断开用户连接吗? - David
我更新了这个例子,这样解决了你的问题吗? - Namysh
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接