Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to create a room based on 2 users in socket.io?

My goal is to create a one to one chat based on two different users. The only way that I could think of is to use socket.io rooms

But the problem right now is that how do i create unique room?

For example

socket.on('join', function(room) {
   socket.join(room);
});

Do i need to emit the room from the client, if so , how do I make it unique. Imagine there are thousands of users.

The chat application, is similar like facebook chat application. Where you can chat one on one.

Do i need redis or mongodb to store the room? Anyone of you who have experience using socket.io in scale, please do share your opinion

Thanks!

like image 769
Jack Moscovi Avatar asked Jan 28 '16 10:01

Jack Moscovi


2 Answers

A room always will be unique, when you do socket.join('roomname') if the room not exist it will created and this socket will join it, if exist the socket just will join it.

So if you want that client A join in the room where is client B for example, from client A you can send a event like:

socket.emit('joinroom', roomname);

On sever:

socket.on('joinroom', function(data){
     socket.join(data)
  })

Anyway when a socket connect , it create and join his own room automatically , the name of this room will be the id of the socket, so i think is not neccessary create new rooms for a chat based on two different users.

Everything that you need is link the socket id with a permanent property of the user.

EDIT:

I leave you here a simple chat app example where you can open multiple conversations:

server.js: https://gist.github.com/pacmanmulet/b30d26b9e932316f54b2

index.html: https://gist.github.com/pacmanmulet/6481791089effb79f25f

You can test it here :https://chat-socket-io-example.herokuapp.com/

I did not use rooms, it have more sense when you want emit to a group of sockets, not to a only one. Hope you can understand better my idea with that.

like image 180
David Perez Avatar answered Nov 14 '22 23:11

David Perez


you need to store the room number somewhere(any database).You have to do this because you have to keep your server stateless.

Let us assume that you are creating a private chat only for two people.The room number has to be unique. so one approach is to use the user's email id and join them to create a new string and emit it back to the users.this is tricky because we don't know the order in which the strings are joined. so we join them by a string not used in normal email name(eg :'"@!@!@!!@!@!@!').we can split it on the server side and compare emit the results.

The actual message body will be

   {
        room:[email protected]@gmail.com,
        from:a,
        message:'hi buddy how are you?'
    }

CLIENT side code

const roomName = [email protected]+'@!@!2!@!@"[email protected]
socket.emit('room', { room: roomName });
    this.socket.on('joined', data => {
        console.log('i have joined', data.room)
        store the room name room: data.room })
    })
socket.on('chat',data=>console.log(`received chat from ${data.from} from the message room ${data.room}`)

used '@!@!2@!@' just because we can separate them on the server side and check if the room already exists.

SERVER side code

 const room =[]//this variable you have store in database and retrieve it when needed.
socket.on('room',data=>{
        if(room.length!=0){
            const temp = data.room.split('!@!@2@!@!').reverse().join('!@!@2@!@!');
            if(room.includes(temp)){
                socket.join(temp)
                console.log('joined room',temp)
                socket.emit('joined',{room:temp})
                console.log(room);
            } else if(room.includes(data.room)){
                socket.join(data.room)
                console.log('joined room', data.room)
                socket.emit('joined', { room: data.room})
                console.log(room);

            }
        }else{
            socket.join(data.room);
            room.push(data.room)
            console.log('joined room',data.room);
            socket.emit('joined', { room: data.room })
            console.log(room);
        }

    })
like image 40
narasimha sriharsha Kanduri Avatar answered Nov 14 '22 23:11

narasimha sriharsha Kanduri