rvc
rvc

Reputation: 11

Socket.IO's io.emit works, but socket.emit / io.to().emit / io.in().emit don't

I'm trying to make a simple instant messaging app and I've been struggling getting the websocket part to work. I'm finding that the client can successfully send requests to the server, but when I try to have the server emit back to the client it only works with io.emit rather than socket.emit, and even using io.emit doesn't work when I try to make it emit to a specific room using to() or in(), which I need it to do. Instead it times out for those.

Client:

      const socket = io('http://localhost:3000');
  
      socket.on('connect', () => {
        console.log('connected to socket');
      });
  
      socket.on('chat-message-out', (msg) => {
        console.log('incoming message thru socket: ', msg);
        setConvoMessages((prevMessages) => [msg, ...prevMessages]);
      });
  
    const sendMessage = (message, recipient) => {
      socket.emit('chat-message-in', message, recipient);
    };

    const joinRoom = (convoId) => {
      
      socket.emit('join-room', convoId);
      console.log('joining room ', convoId);
    };

Server:

io.on('connection', (socket) => {
  console.log(`User connected with socket ID: ${socket.id}`);

  socket.on('chat-message-in', (message, convoId) => {
    console.log(`User ${socket.id} sending message to conversation ${convoId}: ${message.msgtext}`);
    io.to(convoId).emit('chat-message-out', message, (error) => {
      if (error) {
        console.error('Error sending message:', error);
      } else {
        console.log('Message sent successfully');
      }
    });
    
  });

  socket.on('join-room', (convoId) => {
    console.log(`User ${socket.id} joined conversation ${convoId}`);
    socket.join(convoId);
  });

  socket.on('disconnect', () => {
    console.log(`User ${socket.id} disconnected`)
  });
});

instrument(io, {
  auth: false,
});

For this, my server logs:

User cW-J0NoNfpTTMjMKAAAL sending message to conversation BhzO0KukuC4zHb3o: dumb
Error sending message: Error: operation has timed out
    at Timeout._onTimeout (/home/rvcross/repos/messaging-app/server/node_modules/socket.io/dist/broadcast-operator.js:182:17)
    at listOnTimeout (node:internal/timers:569:17)
    at process.processTimers (node:internal/timers:512:7)

but if I were to remove the to() part it will send the message to all sockets successfully.

The "user ____ sending message to conversation" part gets logged out correctly, for what it's worth.

I have used the Admin-UI to confirm that the sockets are in fact in the room (convoId), so I don't think that is the issue.

Any help would be appreciated!

Upvotes: 0

Views: 232

Answers (1)

rvc
rvc

Reputation: 11

Okay, I seem to have gotten it working. The client is written with React, and I had most of the socket stuff in a useEffect, but not where I declared that socket = io('http://localhost:3000'), which I just had at the top with my imports. Whenever the component rerendered it would create a different socket connection, but the previous connections created by previous renders still were out there. I'm not entirely sure how this resulted in the problem I had, but anyway, moving the socket declaration inside the useEffect got the to().emit working properly, although my server is still giving me timeout error messages.

Upvotes: 0

Related Questions