DEV Community

Cover image for An Auction System Needs a Central Clock
Yoram Kornatzky
Yoram Kornatzky

Posted on • Edited on • Originally published at yoramkornatzky.com

An Auction System Needs a Central Clock

An Auction Runs by A Clock

An auction system either live or timed runs by the clock. In a live auction, one often runs calls on a bid according to a clock. In a timed auction, you start and end an auction by the clock, and you show the users a countdown timer.

Browser Times Cannot Be Trusted

In a browser, new Date() gives you the user local time, according to the user's computer local time. As users reside in different time zones, and moreover may have inaccurate computer clock, or they may just intentionally modify that clock, the local time will be different.

Obviously, one cannot let the user observe any time-dependent functionality, and make any time-dependent action, based on a clock which is the same for all users of the auction system.

A Central Clock is Needed

Hence, an auction system logically needs a central clock, and that clock has to be projected to all users in all case where relative times, such as a countdown timer, or absolute times, such as auction start and end times, are observed by the user on a web page. The web page might show absolute times in the user time zone, but the local time has to be derived from the central clock.

Such a central clock has to be implemented at the server, as this is the only place where we can rely on. And needs to be transmitted to the user web page.

Such a transmission can be either upon a time-based event, such as auction start or end or periodically, with the web page adjusting the content dynamically, such as advancing a countdown timer.

The presence of a central clock implies the need for a real-time web application to which the server sends updates.

Alt Text

Implementing a Central Clock

Node.js

Server-Side

Integrate the web page and the server with Socket.IO.

At the server run setTimeout or setInterval, for an event-based action or periodic update, respectively.

Front-End Event-Based

At the front-end listen to a socket event for an event-based auction, e.g.

    socket.on('advanceCall', (data) => {});
Enter fullscreen mode Exit fullscreen mode

Or

socket.on('startAuction', (data) => {});
Enter fullscreen mode Exit fullscreen mode

Front-End Periodic

socket.on('time', (data) => {});
Enter fullscreen mode Exit fullscreen mode

Laravel

Server-Side

Use ReactPHP to implement a timer, either periodic,

$timer = $loop->addPeriodicTimer($time, function() 
    use(&$task) {
broadcast(new TimeSignal(json_encode(...)));
});
Enter fullscreen mode Exit fullscreen mode

where TimeSignal is a Laravel event.

Or one time,

$timer = $loop->addTimer($time, function() 
    use(&$task) {
         broadcast(new AuctionCall(json_encode(...))); 
});
Enter fullscreen mode Exit fullscreen mode

where AuctionCall is a Laravel event.

For more details, see my article Timer Server in ReactPHP.

Events are broadcast using Laravel Echo Server or Laravel Websockts

Front-End

Listen for events with Socket.io,

window.Echo.channel('auction-events')
  .listen('startAuction', (e) => {

  });
Enter fullscreen mode Exit fullscreen mode

Or

   window.Echo.channel('time-signal')
   .listen('time', (e) => {

    });
Enter fullscreen mode Exit fullscreen mode

Top comments (0)