0

I succesfully implemented a real-time chat in specific 'room' with Socket.io-client.

And now, I want to make every message from every room make an alert from everywhere in my page even though the user doesn't actually enter every room.

So, I wrote codes like this.

const socket = io(server-url);

This Socket is managed with useContext. (The socket is connected in the ContextProvider)

useEffect(() => {
  socket.connect();
});

And I made this socket gets global messages in the layout.js where the <Header/>, <Footer/>, <Outlet/> is placed. Sadly, it doesn't work. I don't have an access to the server code, but I know that there's no problem in the server.

const { socket } = useChatData();

useEffect(() => {
  socket.emit(`connect`, { socket: socketID });
  if (chats)
    socket.on("newMsg", data => {
    console.log(data);
  });
}, [socket]);

This code doesn't make any error, so I couldn't catch what's the problem. How can I solve this? I'll also be very happy for some feedbacks or advices for the concept or method of global messages with socket.io-client that are not related with my codes.

Ha_AH
  • 1
  • 1
  • Are you talking about [broadcasting](https://socket.io/docs/v3/broadcasting-events/)? – Mike 'Pomax' Kamermans Aug 16 '23 at 16:40
  • I think this is a slightly different concept. In broadcasting, if my understanding is correct, the server sends the same message to connected clients. But I want some function that sends some notification of new messages from every room in ''the user's namespace''. But now, only when the user joined a specific room, the alert for that room is activated. – Ha_AH Aug 17 '23 at 05:06
  • Note that socket.io _has_ namespaces, and you can broadcast to just a single namespace. – Mike 'Pomax' Kamermans Aug 17 '23 at 14:52

1 Answers1

0

It's not clear to me the issue, but I hope the following actions can help you:

  1. Modify Dependency Array:

    • Update your useEffect's dependency array to:
    }, [socket, chats]);
    
  2. Clean Up Event Listeners:

    • Ensure you remove the event listener when the component unmounts.
    useEffect(() => {
      const handleNewMsg = (data) => {
        console.log(data);
      };
      if (chats) {
        socket.on('newMsg', handleNewMsg);
      }
      return () => {
        socket.off('newMsg', handleNewMsg);
      };
    }, [socket, chats]);
    
  3. Avoid Multiple Connections:

    • Disconnect the socket when the component unmounts:
    useEffect(() => {
      socket.connect();
      return () => {
        socket.disconnect();
      };
    }, []);
    
  4. Rename the Emit Event:

    • Change your connect event name to something like "userConnect".
  5. Place Listener in Higher Component:

    • Ensure your socket listener is in a component that doesn't unmount often (e.g., App component or Context Provider).
  6. Double-Check Server Events:

    • Confirm the server emits the "newMsg" event to the right client or room.
  7. Singleton Socket Instance:

    • In your context, ensure there's only one instance of the socket for the entire app.

Start by implementing these steps individually, testing in between to pinpoint and resolve the issue.

Greg Uretzky
  • 120
  • 5