Home > front end >  how to emit socket io to specific logged in user?
how to emit socket io to specific logged in user?

Time:09-25

I am using socket.io with express and typescript, when want to emit to particular logged in user it is not working, the rest is working fine, when new user join and other things, in App.ts in backend it looks like:

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");
  });
});

and in another route 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);
};

the like post route looks like

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 });
};

in the frontend react app just calling it like:

  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>

any help please?

CodePudding user response:

I believe you need want io.in

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

Ref

  • Related