My FeedDiscussionsHeadless CMS
New
Sign in
Log inSign up
Learn more about Hashnode Headless CMSHashnode Headless CMS
Collaborate seamlessly with Hashnode Headless CMS for Enterprise.
Upgrade ✨Learn more
Building  a synchronous timer between two client in a websocket

Building a synchronous timer between two client in a websocket

How we built a highly synchronous timer of a fiat currency trading application.

Olaniyi Philip Ojeyinka's photo
Olaniyi Philip Ojeyinka
·Oct 2, 2021·

4 min read

In my previous article here , i wrote about about how to use redis to publish data to and fro between two separate services.

Before getting deep in to discussing these, will like to write about what we wanted to achieve and why we are choosing these approach ,what other approach we could have go with and their short comings while also not forgetting what we could have trade off in each options.

The Goal is to display a highly sync,secure timer between two traders in a trading transaction . We want to make sure the timer cannot be compromise from the client side and also want to make sure that we are doing less processing in clients' side especially on the mobile version of our clients; we pushed more of the processing to the server.

We could have have use either of the two approach below:

POLLING : Polling is the process where the client make an time interval request to the server to get new status of data/data itself(update). We have two types of polling :SHORT and LONG in SHORT , we make a request to the server in a certain time interval to get the latest data while in LONG we make a request also at a certain interval but if there is no new updates , the request will be on hold untill we got new one.

The drawback of this approach in our use case is that ,in situation where we have couple of trades happening simultaneously , we will be sending a request every seconds for every trades and every clients involve in the trade,This will overload our server as more resourceses will be utilized in the process establishing tcp/http/https connections and not talk of time taken to handle both serialization and deserialization of payload across both ends.

SEPARATE FRONTEND/BACKEND TIMING : another approach we could have used is to maybe get the time started in both clients and continue to count then check if time has elapsed or not when a client make request to the server relating to the transaction. The drawback of this approach in our use case is that we can't guarranty the precision of the timing between different devices,server timing and also we want move all processing to backend as much as possible.

So with socket , we eat our bread and still have it 😊 Websocket allow us to establish a long bi-directional connection between client and server. In these article ,we be using the socket.io library on nodejs.

To get started with socket.io on nodejs,please follow this link

We made sure that only those who are involve in the trade get the right timer and avoid mixed up by attaching a unique uuid of a trade to the event we are using for the timer for example ,in trade with uuid yhgd34gxfds we can listen to the event `trade${uuid}timer' in the backend as below

When either of or both participating party emit payload object to the trade{xxx}timer from the frontend, the time calculate the remaining time from the expiry value and its created at timestamp, this way, we are pretty sure both party get the same timing at anytime.

//uuid here is the uuid of the trade making it easy to avoid mix up
io.on('connection', (socket) => {
  socket.on(`trade${uuid}timer`, (msg) => {
//client for example may send the uuid to this event as a payload during connection initialization
    io.emit(`trade${uuid}timer`, 'timer');
  });
});

 const timers = {};
    timers[`timer${uuid}`] = setInterval(function () {
    //start your countdown
   //emit current time e.g 2:08:04

 io.sockets.emit(`trade${uuid}timer`, {min:5 , sec:2,mili:07});
},1000);

Saving each timers in an object just in a case, we have both party having two separate trade going on simultaeneously, we may need to clear a specific timer when time is up or when a party release fund from escrow (successful trade) using the object as follows


clearInterval(timers[`timer${uuid}`]);

Most importantly, javascript time/date object/functions/methods will work with the time on the machine it’s running on ,doing this in the server side means any connected clients are show a sync timing as all what the clients are doing in this case is just rendering of the countdown.

Could this have been better? got any concerns? lets discuss in the comment section below.