It's easier to Implement Websocket in a Group Chat

@marvel1206 · 2022-11-01 10:10 · Programming & Dev

Grey Minimalist Hello Facebook Cover (4).png

In this episode of building a Chat, we are going to go over how to implement Web sockets in a group chat. Before I did this, I had this unnecessary phobia about how I was going to go about it. I mean, for 1-1 chat we could just emit the socket to the other party. But we have a group, full of people, do we emit the socket to an array of members individually? That would be expensive to do.

The optimal solution involves the use of socket.join method. When a user opens a Chat, he essentially joins the chat id - if any. Or you can identify it with a socket id.

DEMO:

Video_20221101105908011_by_videoshow.gif

My group chat has an ID so I just had to create a useEffect on the group chat page that emits an event to the backend, my server runs on port 5000.

socket.current = io("http://localhost:5000")
            socket.current?.emit("join-chat", selectedGroup._id)

This is wrapped in a useEffect function. Selected Group Id is the ID of the group, could as well be the default generated Socket ID. 

On the server is where we use the socket join function, this is the most important part. The user joins the chat

    socket.on("join-chat", (id)=> { 

         socket.join(id) 
         console.log(`A user joined ${id}`) 
     })


The id is the selected Group Id coming from our frontend.

When a new message is sent, We update the chat state so the screen can be updated with the sent message. All these is writing in the sendChat arrow function

 dispatch(sendMsg({from:user._id, groupId: selectedGroup._id, message: message, userId: user._id})) 
                 groupChats = [...groupChats]; 
                 groupChats.push({fromSelf:true, message: message}) 
                 dispatch(addGroupMessage(groupChats))  

                 setMessage("");

We define a payload

                let payload = {id:selectedGroup._id, data: { 
                     message:message, avatarImage: user.avatarImage, 
                     nickname: user.name, id: user._id 

                     } 
                     }


Then we emit the event to the backend. The groupId is contained in the payload.

socket.current.emit("send-groupMsg", payload) 

 I know right, I'm bad at naming. 



On the server

    socket.on("send-groupMsg", (data)=> { 
         socket.broadcast.to(data.id).emit("message", data.data) 
     })


We emit the message event to the groupId, the socket.broadcast.to emits the event to all users but the sender. This is a very useful feature.

In the same group chat component, in another useEffect function we want to listen to the socket

useEffect(() =>{

socket.current.on("message", (data)=> { 
                
                      
                     groupChats = [...groupChats]; 
                    groupChats.push({fromSelf:false, message: data.message, details: { 
                         avatarImage: data.avatarImage, 
                         nickname: data.nickname, 
                         _id: data.id 
                     }}) 
                      
                      
                     dispatch(addGroupMessage(groupChats))  

                 } 

}, [groupChats] ) 


The groupChats in the useEffect dependency array is vital. I encountered this bug when I failed to put it

Video_20221101105559839_by_videoshow.gif

The current chat list won't be gotten when there's a new socket if we don't put it

And that's about it, we update the state with the incoming message so that our chat screen can get updated in real time.

Follow for more❤️

#hive-169321 #programming #stem #javascript
Payout: 0.000 HBD
Votes: 7
More interactions (upvote, reblog, reply) coming soon.