如何向特定登录用户发出套接字 io?

how to emit socket io to specific logged in user?

我正在使用 socket.io 和 express 和 typescript,当想要发送给特定的登录用户时它不起作用,其余的工作正常,当新用户加入和其他事情时,在 App.ts 在后端看起来像:

httpServer.listen(8000, () => {
  console.log(`app is running on: http://localhost:8000`);
});

//SocketIO
const io = new Server(httpServer, {
  cors: {
    credentials: true,
  },
});

app.set("socketio", io);

io.use((socket: SocketWithUser, next: any) => {
  const token: any = socket.handshake.query.token;

  if (token) {
    try {
      const payload = jwt.verify(
        token,
        <string>process.env.JWT_TOKEN
      ) as DataStoredInToken;

      socket.userId = payload._id;
      return next();
    } catch (err) {
      next(err);
    }
  } else {
    return next(new Error("Access Denied"));
  }
});
io.on("connection", (socket: SocketWithUser) => {
  if (socket.userId) {
    socket.join(socket.userId);

    socket.emit("joined", `user ${socket.userId} joined`);
  }

  socket.on("disconnect", () => {
    console.log("disconnect");
  });
});

在另一条路线中 sockethandler

import { Request } from "express";
import { NotificationProps } from "types/notification";

export const sendNotification = (
  req: Request,
  notification: NotificationProps
) => {
  const io = req.app.get("socketio");

  io.sockets
    .in(String(`${notification.receiver}`))
    .emit("newNotification", notification);
};

相似的post路线看起来像

export const likePost = async (req: RequestWithUser, res: Response) => {
  const { postId } = req.body;

  const post = await PostModel.findById(postId);

  if (!post) return res.status(400).send({ msg: `post does not exist` });

  const checkIfLiked = post.likes.find(
    (item: any) => String(item.user._id) === String(req.user_id)
  );

  if (!checkIfLiked) {
    await post.updateOne(
      {
        $push: { likes: { user: req.user_id } },
      },
      { new: true }
    );

    const notification = new Notification({
      sender: req.user_id,
      receiver: post.user,
      notificaitonType: "like",
    });

    await notification.save();

    sendNotification(req, notification);

    return res.status(200).send({ success: true });
  }

  const postWithOutLike = await post.updateOne(
    {
      $pull: { likes: { user: req.user_id } },
    },
    { new: true }
  );

  return res.status(200).send({ postWithOutLike });
};

在前端 React 应用程序中,就像这样调用它:

  socketIo().on("newNotification", (data) => {
    console.log({ data });
  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

有什么帮助吗?

我相信你需要 io.in

  // to all clients in room
  io.in(notification.receiver).emit('newNotification', notification);

Ref