Sending data via websockets vs api route

I’m developing a chat application, which currently uses websockets to send/ receive messages. I’m implementing an offline/online user system for the react client, so that involves having to query my db for the total users inside a room, and using websockets to get the online users, and using that to filter for the offline users. So I have to use a call for retrieving the total users. Currently in my clientside code, I have a join room method such as:

const joinRoom=()=>{
//make api call to server to update db, showing that it has joined the room
//based on results of clientside code, display that the user has joined the room
//join the socket io room
//at this point, need to retrieve the total users that have joined the room so i can create offline/online users lists
}
I can either emit a socket event to retrieve the offline/online users, where the node server will query the database, get the online users as well, and transmit both the arrays, or I can make an api call in my clientside route, get the total users in the room, emit a socket event to get the online users, retrieve them, and filter them based on their usernames. Something to keep in mind is that I would also retrieve their profile pictures via binary data, and convert them clientside. Which of these approaches would be more efficient/ best practice for a chat application? On a side note, how would I test what would be more taxing on my server, and see the speed difference of both of them?

I don’t think there would be any need to use a DB to store users active in a room. When the user logs in, you would check the DB to be sure their credentials are correct. Then, you could just place their socket in the room in question and they will be logged in. I wouldn’t store room status in the DB.

This has the advantage of not needing to hit the DB later to see who is online. You’ll know who is online because they have a socket connected.

My database just shows if they are currently signed up/subscribed for a chatroom, like a discord server. if a user logs out and logs back in, they’ll still see their chatrooms automatically, rather than having to manually rejoin each one. As soon as they open the chat page, they’ll join the socket room for each room that that they are subscribed to, and can see and send messages from others. I still need to implement offline/online users, so I have to make a query to my database to get all of the users that are currently subscribed to the chatroom, whether they are online or not.

The two approaches are like this: join the socket room clientside=> emit join event to socket server =>socket io code will query db to get the total users that have subscribed to the room=> socket io gets the online users and their information via socket ids and info stored=>set online users to the online information=>filter online users from total users to get offline users=>emit both arrays to client=>client displays both, and modifies them later based on what users in the chatroom do like disconnect or leave the room

other approach: client joins socketroom=>makes api call to server route=>db is queried=>returns totals users to route=>route returns total users to client=>socket room join is emitted from client=>socket io gets online users based on socket ids and info stored=>socket io emits to client side the online users array=>client receives online users, filters out from total users to get offline users=>client displays both, and modifies them later based on what users in the chatroom do like disconnect or leave the room.

I think the first approach is more realtime, but I’m still not sure which approach would be considered best practice for a chat application, and if there is a significant difference in performance. Hopefully this clears up the workflow of the application

Ah, I gotcha. I personally would create the socket connection immediately upon joining the room. It just feels cleaner than having a single chatroom interface using both fetch and socket connection methods. All the querying can be done afterward as necessary.