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.
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.
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.
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) => {});
Or
socket.on('startAuction', (data) => {});
Front-End Periodic:
socket.on('time', (data) => {});
Laravel
Server-Side
Use ReactPHP to implement a timer, either periodic,
$timer = $loop->addPeriodicTimer($time, function() use(&$task) {
broadcast(new TimeSignal(json_encode(...)));
});
where
TimeSignal
is a Laravel event. Or one time,
$timer = $loop->addTimer($time, function() use(&$task) {
broadcast(new AuctionCall(json_encode(...)));
});
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) => {
});
Or
window.Echo.channel('time-signal')
.listen('time', (e) => {
});
Previously published at https://yoramkornatzky.com/post/an-auction-system-needs-a-central-clock