Socket.io – How to Connect Two Users in a Lobby

node.jssocket.iowebsockets

first of all i will explain you what i want to do.

I have a Web application where are multiple rooms like Room1, Room2, Room3…
Currently active users can join in one of these Rooms by clicking on it. I handle this with socket.io rooms. That means, if a user clicks Room1, he will join this room by socket.join(„room1“). A room can have many users. But every user in a room can only conntect to exactly one user. That means if user1 joins Room1 he needs to get connected to an other user in Room1 which has no partner yet. If two users of a room are connected with each other its not possible for a third user to get connected with these already connected users. This third user which has no partner yet have to wait for a fourth user, who has also no partner. The difficult part is, if a user1 and user2 are connected together, and for example user2 wants to switch his partner by clicking on a button, than user1 needs to get a new partner and user2 also. That means, all users in a room need everytime a partner.

Iam not really sure how to handle this.

Actually if two users are connected, iam setting a state on the socket like connected = true. So everytime if a user have to find a partner, it will look in socket.io room1 for a user which has connected = false. And after they are connected, i set connected = true. And if for example user2 click on „switch partner“, i set connected to false for both. And both of them starts searching for a new partner.

On my frontend if i need to find a Partner i send a request to my backend to start searching by getting first all sockets of a room in an array.
Than i start looking for a socket in this array who has connected = false. If i find one, i set for both connected = true and starts to share information. If i couldnt find a free partner, iam sending a new search request from my frontend, until i find a partner.

Now the problem is. If for example user1 starts searching for an other user in this array. And at the same time a other user (user5) start searching also a user in this array. Its possible that user1 gets for example user3. But user5 gets user1. That mean i can never be 100% sure that every user has only 1 Partner.

Like you hear, its very complicated and really prone for errors. Maybe there are other and more cleaner ways to handle this. I am grateful for every suggestion.

I hope you understand my problem and have a good idea to handle this.

Best Answer

Now the problem is. If for example user1 starts searching for an other user in this array. And at the same time a other user (user5) start searching also a user in this array. Its possible that user1 gets for example user3. But user5 gets user1. That mean i can never be 100% sure that every user has only 1 Partner.

What you describe here is called a race condition and it is a well-known problem in systems where concurrency is possible and it has no universal solution.

One way to solve your race condition is to have one, singular, server-side component that handles the requests for connecting two users in a room. This component can then either indicate that the connection request succeeded or that, by the time the request got processed, one or both of the partners were no longer free for a new connection.
This component can take the form of a 4database server using transactions, or an API endpoint that queues the requests and handles them one after the other.

Note that if the user-selection is done manually by the end-user, then your system could have the result that a user gets connected to someone they didn't select. To take your example, if the request from user5 gets processed first, then user1 would be connected to user5 and not the one they choose (user3).