I'm in a bit of a pickle. Not sure what I'm doing wrong here.
The abstract logic is like this:
Here is the issue. I have one user create a chat and add the second user to it. When I refresh either of the pages of the users, only one of them gets added to the room. If I refresh the first users page, then the second user gets added to the room, and vice versa.
At no point do both of them get added to the same room.
Here are screenshots of my implementation.
Server:
const sockets = new Map<string, number>();
io.on('connection', (socket) => {
// console.log({sockets: io.sockets.adapter.sids});
socket.on('newUserJoined', async (data: { chatIds: number[], user: number }) => {
if(!data.chatIds || !data.user ) return;
sockets.set(socket.id, data.user);
socket.join(data.chatIds.map(t => `room${t}`));
// console.log('connect', {user: data.user, date: new Date()})
// console.log({ rooms: data.chatIds.map(t => `room${t}`) });
console.log('Connecting socket', { id: socket.id, user: data.user, chatIds: data.chatIds });
io.to(data.chatIds.map(t => `room${t}`)).emit('onlineUsers', [data.user]);
});
socket.on('disconnect', () => {
let rooms = Array.from(io.sockets.adapter.sids.get(socket.id) ?? []);
for(var room in rooms) {
socket.leave(room);
}
console.log('Disconnecting socket', socket.id);
sockets.delete(socket.id);
// console.log({onlineUsers: Array.from(sockets.values())});
io.to(rooms).emit('onlineUsers', Array.from(sockets.values()));
// console.log('disconnect', {onlineUsers, date: new Date()})
});
socket.on('sendMessage', (message: { text: string, chatId: number, senderId: number }) => {
io.to(`room${message.chatId}`).emit('getMessage', message);
});
});
Server explanation:
Client:
useEffect(() => {
if(!socket || !user?.id || !chatResponse || chatResponse.data.length == 0) return;
console.log({chatResponse});
socket.emit("newUserJoined", { chatIds: chatResponse?.data.map((c: ChatFull) => c.id), user: user.id });
socket?.on('onlineUsers', (ids: number[]) => {
console.log('Online users', {ids});
setOnlineUsers([...onlineUsers, ...ids]);
});
return () => {
socket.off('onlineUsers');
}
}, [chatResponse]);
Client explanation:
Any help on this? Maybe my approach is wrong to the problem. I can't really find a guide when there are multiple chats, that can exist during connection, and multiple users in any given chat.
In the newUserJoined
event handler, you are only sending the just logged-in user. You should send all of them. Change this line
io.to(data.chatIds.map(t =› 'room${t')).emit('onlineUsers', [data.user]);
to
io.to(data.chatIds.map(t =› 'room${t')).emit('onlineUsers', Array.from(sockets.values()));