📜 ⬆️ ⬇️

Instant PlanningPoker on socket.io

Motivation


Once in the icy winter season during the next planning meeting at work, where everyone used his voting tool - paper maps, various phone apps , etc - I was wondering if everyone could sit in the same room when planning could be done from their workers. places, or even from home.

So the idea is to make a remote scheduling service using the Planning Poker technology so popular in the agile world. It is also a little better to understand how socket.io and related technologies work.


Formulation of the problem


Develop a page by which the user enters his name and “room”, then one of the users sets the task in question, everyone votes - when the last of the group has voted - the cards open.
')

The first attempt to implement the protocol


So, having read this article - the first thought: the browser is a thin client, all logic and state are stored on the server as soon as a new client is connected to a certain room - the server sends out a new snapshot of the state of the room to everyone. The same happens when customers vote, change the topic of discussion, etc.

However, this approach requires some storage on the server (I wanted to avoid using the database, because I wanted to host the project as free as possible). As an option to keep the state in memory - an array or some kind of complex object, but this is fraught with memory leaks.

Second and final implementation


The second approach to solving the problem was to make each individual client responsible for storing his own state and exchange of states with all participants. If we abstract away from socket.io, the protocol can be explained as follows - polite people in a dark room:

The last point does not fit into the rules of politeness - since the client cannot notify everyone about his disconnection, this function had to be placed on the server - it is the server that is responsible for telling others about the departure of one of the participants:

  socket.on('disconnect', function () { var rooms = that.__io.sockets.manager.roomClients[socket.id]; for(var room in rooms) { if ((room != '') && (rooms[room])) { /*removing a slash*/ room = room.substring(1); that.__io.sockets.in(room).emit('leave', { room : room, id : socket.id }); } } }); 


Separately, it is necessary to mention the support of rooms in socket.io, which is not mentioned on the official. site. I got a lot of information from here . By and large rooms have a logical way to separate all clients connected to the server.
You can enter the room or leave it only from the server side, at the same time you can be in several rooms:

 socket.join('room'); socket.leave('room'); 


The rest of the north - just proxies messages between clients in the same room. The only “business logic” on the server is a restriction on entry into rooms to 12 people. For example, sending an update message in the north looks like this:

  /*sending update*/ socket.on('update', function (data) { /*notify everyone*/ data = that.identify(data, socket); that.__io.sockets.in(data.room).emit('update', data); }); 


Customer

All the logic we have on the client. He is responsible for voting the client (choosing a card), decides when to show the cards of other participants, drops votes when a topic changes and / or new people come. The client also publishes events - this is done in order to separate the client's business logic from the actual manipulations with the DOM, etc. It looks like this:

 client.on('reveal', function(){ $('.flippable').each(function(i, val) { setTimeout(function(){ $(val).addClass('flipped'); }, i*50); }); }); 


Conclusion and Demonstration


In conclusion, I want to say that this approach, though it proved to be not bad, is not without flaws - i.e. There is an opportunity to get into the logic of the client and thus break the synchronization between participants. Also, the votes arrive as soon as someone has voted, they are just not visible until everyone has voted, however, with clever manipulations in Firebug, you can peek at the voices of others.

As a development, you can implement the calculation of the maximum, minimum and average values ​​of maps, as well as implement a simple chat between people in the room - to discuss topics.

as it turned out at the very last moment, Heroku does not support websockets, and had to roll down to long polling - therefore, the demo offered to you is deprived of one important opportunity - the client does not know in time that one of the participants disconnected, this event does not occur. For a complete familiarization, I suggest you clone this repository on Github and run it on a local machine, the server script does a check on Heroku and, not finding it, works in a regular way with websockets. Also, for full testing, you will need 2 or more participants.

Good luck!

Source: https://habr.com/ru/post/170137/


All Articles