Search code examples
c++boostboost-asio

Auctions in Boost ASIO


I'm implementing an auctioning system in C++ with Boost.Asio. There is a single centralized auctioneer (the server) and some connecting bidders (the clients). I am implementing this in an asynchronous fashion, and I have implemented the basic communication between the bidder and auctioneer (register, ping, get client list). The skeletal code for the auctioneer would look like follows:

class talkToBidder : public boost::enable_shared_from_this<talkToBidder>
{
// Code for sending and receiving messages, which works fine
};

void on_round_end()
{
  // Choose the best bid and message the winner
  
  if (!itemList.empty())
    timer_reset();
}

void timer_reset()
{
  // Send the item information to the bidders

  // When the round ends, call on_round_end()
  auction_timer.expires_from_now(boost::posix_time::millisec(ROUND_TIME));
  auction_timer.async_wait(boost::bind(on_round_end));
}

void handle_accept(...)
{
  // Create new bidder...

  acceptor.async_accept(bidder->sock(),boost::bind(handle_accept,bidder,_1));
}


int main()
{
  // Create new bidder and handle accepting it
  talkToBidder::ptr bidder = talkToBidder::new_();
  acceptor.async_accept(bidder->sock(),boost::bind(handle_accept,bidder,_1));

  service.run();
}

My issue is, I need to wait for at least one bidder to connect before I can start the auction, so I cannot simply call timer_reset() before I use service.run(). What is the Boost.Asio way to go about doing this?


Solution

  • In asynchronous protocol design, it helps to draw Message Sequence Diagrams. Do include your timers.

    The code now becomes trivial. You start your timer when the message arrives that should start your timer. Yes, this is shifting the problem a bit forwards. The real point here is that it's not a Boost Asio coding problem. In your case, that particular message appears to be the login of the first bidder, implemented as a TCP connect (SYN/ACK) which maps to handle_accept in your code.