Reputation: 67
My goal is when A user click on B user, they'll join in a room. I'm holding socket.id in array for all clients.
//CLIENT SIDE FOR A//
$('.chat-start').on('click', function(event) {
event.preventDefault();
var room_id = '72xaz132s'
var target_id = $('.target').data('id');
socket.emit('force join room', room_id, target_id);
});
//SERVER SIDE FOR A AS AN EXAMPLE//
var clients {'customIDA' : socket.id for a, 'customIDB' : socket.id for b}
socket.on('force join room', function (roomid, customIDB) {
socket.join(chat_id); //CLIENT A JOINS ROOM//
})
Client A joins room without problem, but how can i add also client B on same room ?
Upvotes: 6
Views: 5843
Reputation: 165
For anyone facing a similar issue.
@Kouvolan Arnold's solution will work but having to store the socket object for each user is too much of a resource, especially when socket.io already stores them.
A simple solution here is for you to get the socket object already stored by locating it. The good news is that socket.io already provides that, see below.
//v2.x or less
io.sockets.sockets[USER_SOCKET_ID_HERE]
//v3.x and 4.x
io.sockets.sockets.get(USER_SOCKET_ID_HERE)
The code below would have worked well in your case.
//v2.x or less
io.sockets.sockets[clientSocketId].join(roomid);
//v3.x and 4.x
io.sockets.sockets.get(clientSocketId).join(roomid);
Thanks
Upvotes: 1
Reputation: 41
This method is a bit of a hack, but it does allow you to force any specified socket into a room entirely server-side, once you have their socket ID, without maintaining another object array. SocketIO (v2.x) stores room allocations in two places to make things fun.
// $targetSocket is the socket ID of the connection you want to force into a room
$roomArray = $io->sockets->connected[$targetSocket]->rooms; //socket's rooms stored here
$roomArray[$newRoom] = $newRoom; // add the new room to this array
$io->sockets->connected[$targetSocket]->rooms = $roomArray; // save the modified array
$io->sockets->adapter->add($targetSocket, $newRoom); // update the adapter too
This is obviously PHP but it will translate easily into js.
You can do the reverse to kick users out of rooms too:
unset($roomArray[$oldRoom]); //delete room key and value from this socket's array
// save the array here, see above
$io->sockets->adapter->del($targetSocket, $oldRoom); // delete from adapter
Use both at once for a leave and join system.
This may seem pointless when a socket can add or remove itself so easily with socket->join('ROOM'); but there are circumstances in which you may need to do this from outside the connection's socket, such a game function.
Upvotes: 0
Reputation: 76
In io.on("connection")
you can store socket object with user id as a object
{"socket": socket, "id": user_id}
to array. Then find index from array:
let user_index = users.findIndex(user => user.id == user_id);
And finally join to room.
let socketB = users[user_index].socket;
socketB.join('room');
Upvotes: 6
Reputation: 1
Maybe handle it server side? Have a dictionary that stores User Ids and the Socket Id, you can store this information io.on("connection")
. Then when User A does the process of creating the room, send to the server side the room id and something that identifies User B. Server side figures out the socket id of User B and joins them to the room.
Upvotes: 0
Reputation: 2148
You can call join to subscribe the socket to a given channel:
// On connection join room
io.on('connection', function(socket){
socket.join('ROOM ID');
});
And then simply use to or in (they are the same) when broadcasting or emitting:
io.to('some room').emit('some event');
To leave a channel you call leave in the same fashion as join.
Documentation: https://socket.io/docs/rooms-and-namespaces/
function join() {
// Run's once clicked
console.log('Join function here');
}
<a href="#" onclick="join()">Join</a>
Upvotes: 0