skip to Main Content

I am building a chat messaging application using Socket Io and Node js. Currently, whenever a user loads the app, they are connected to their own room, with their user Id (coming from the database) as the room name. This is so I can handle sending events to particular users in my application. The code for this looks as follows:

socket.join(user.userId);

Users can create chats, which can contain 2 or more users. When a chat is created, so is a room. Currently, whenever a user sends a message, an event is emitted to the entire room like so:

io.to('chatname').emit('Chat message', msg)

However the problem I have is that I only allow users to join the chat rooms whenever they click on the chat page. This means that they wouldn’t receieve the new messsage if they were on a different page as they wouldn’t be a part of that room. I want users to still receieve messages, regardless of the current page they are on.

A solution to this would be sending message events to a users personal socket (the room they join when they connect), instead of sending the event to the room like the code above. This would look like this:

users.forEach(user => {
    
 // Sending to indivdual users room which they join when connecting.  
 // This would replace the code above, therefore all messages would be sent directly to the users personal room instead of the actual chat room.
 io.to(user.userId).emit('Chat message', msg)
})

I am wondering whether this code is less efficient than sending to the room itself like I am currently doing, due to having to loop over each user and sending the event to their individual room. Is sending directly to the room better practise and more performant? Also, could joining the user to their own room be inefficient due to the fact that socket io already joins users to their own room, with the name being their socket id? I do this so it is easier to send events to specific users, however is this considered bad practise? Thanks.

2

Answers


  1. my advise is.

    1. rooms should be unique and separate from users
    2. rooms should contain users
    3. on your app (frontend) allow the user to signin/authenticate with you backend
    4. once authed, give the users a list of all current rooms.
    5. also allow the user to create a new room, whether there is rooms or there are no rooms in that list
    6. each room should have an owner, so when a room is created, set the owner_id to be the user_id of the created user
    7. then allow the user to click on an existing or their own chat, allowing them to join the room
    8. you could save in the database which user’s are in each room.
    9. when a user is viewing a room you can just use nodejs with socket to communicate each message to said room users, also add the message to the database. so that when a users first joins and starts the initial viewing of the room will then receive a bulk messages, so that their chat view will be caught up to the actual chat room.

    Recap

    DB Tables

    Room:
       ID
       Name
       Owner_ID
    
    RoomUsers:
       ID
       User_ID
       Room_ID
    
    User:
       ID
       Name
       Email
       Password
    
    Message:
       ID
       Room_ID
       Sender_ID
       Message
    
    Login or Signup to reply.
  2. This seems like an architectural rather than a programmatic issue. I suggest that you maintain the state between the client and the server. This means that each user can still recieve information on any room they join as long as they haven’t performed an action to leave a room such as clicking a "Leave room" button.
    Your first solution which is:

    io.to('chatname').emit('Chat message', msg)
    

    is the correct implementation. So this is most likely an issue of storing state and architecture.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search