Please get a room!
The biggest room in the world is the room for improvement.
Helmut Schmidt
Last week, we introduced SocketIO and the wonderful world of real-time communication between users.
But privacy was not on the menu, as anytime you would make a change to the selected cards, it would update every other clients.
So, in our game, we actually need to introduce “rooms”, a place where a set of users will have their own game, independently of other people.
As a requirement, we also want users to be able to create or join a game without having to log in, just by creating a random URL such as:
http://www.plannipoker.com/games/ABCD
The ABCD above will be a random string, that the users can either enter themselves or the app would create for them.
The first user hitting this URL would make the server create the game, and every subsequent user would join the game automatically.
The Server side (commit)
On the server, at the moment, any SocketIO message is broadcast to everyone.
We now need to change that so when a user joins a game, he joins a “room”, whose ID will be the ID of the game (the ABCD in our example above).
But beforehand, let’s define a set of actions that will be shared by both the server and the client: you can see them in both server/actions.js for the server and src/actions.js for the client. These are plain strings that will help identify which message we are sending between our app and our server.
Then, on server/index.js is where the interesting bits are: on line 30, we define an object that will store our data, for all rooms. It’s initially empty, but every time we will try to get the data for a specific room, we will call getRoom
on line 33, which will either create the room with an empty set of cards if it doesn’t exist, or return the room if it does.
Then, for each of these actions, we want to define a handler that will respond accordingly (see line 81). We get the room , and call the handler that corresponds to the action.
The Client side (commit)
Getting the room name
First, we need to get the name of the room. In a future iteration, we will be using a proper router such as react-router, but to keep things simple today we will just get that value from the URL.
We expect the user to go to the following path: /games/SOME_ID where SOME_ID is something random.
The getSessionId
method on the component will read the URL from the window object, strip out the /games/ part, and return the Game ID.
Joining the room
Also, as soon as we connect to the server (when the component mounts), we need to join the room, which we do on line 48 by specifying the room ID.
Sending the card selection to our room
Then when we need to send our new selection, we get the room ID to let the server know which room we are in and send the cards as the payload. You can find an example of this on line 69, where we send both the room ID, and the actual payload.
Trying it out
If you run the project (yarn start
remember?), and open two browser windows on http://localhost:3000/games/helloworld, you will see that the cards selection is synchronised! And if you change the game ID, you’ll see that you’ll get another set of cards.
Next Week
We will clean our code a bit and introduce the concept of users, so people can see who is connected to their game.