I'm trying to write a udp message heartbeat function with Boost asio. How would I create a boost asio timer that takes some action if a UDP message does NOT arrive within a prespecified timeout?
Right now I have a boost asio application that fires a udp status datagram message based off a timer boost::asio::steady_timer
that fires @1HZ. I need the counterpart receiving application to take some action, i.e. (log a warning) if the packets do not arrive within a 2 second window (for ex).
For clarity here are the relevant parts of my heartbeat status sender application. It uses the following heartbeat timer callback to send the datagrams.
std::unique_ptr<boost::asio::steady_timer> mpStatusTimer;
void
Daemon::heartBeatTimer(
const milliseconds& rHeartBeatMs)
{
static auto& gEvtLog = gpLogger->getLoggerRef(
Logger::LogDest::EventLog);
// changed from absolute expires_at (previous + rHeartBeatMs) to
// expires_from_now to account for background change in the system
// time from the CMC
mpStatusTimer->expires_from_now(rHeartBeatMs);
mpStatusTimer->async_wait(boost::bind(
&Daemon::heartBeatTimer, this, rHeartBeatMs));
// send status udp packet
mpTransmitSocket->async_send_to(
buffer(mpStatusMessage.get(),
sizeof(MemberSystemStatusMessage)),
mEndpoint, boost::bind(
&Daemon::handle_send_status,
this, _1, _2));
}
And the async send callback is as follows: Note that the timer keeps the asio's IO_Service busy by reprogramming the timer each time - thus the handle_send_status does not need to do anything to the IOService
void
Daemon::handle_send_status(
const boost::system::error_code& error,
std::size_t bytes_transferred)
{
static auto& gEvtLog = gpLogger->getLoggerRef(
Logger::LogDest::EventLog);
if (!error || (error == boost::asio::error::message_size)) {
if (bytes_transferred == sizeof(StatusMessage)) {
// log the message only if changed
if (!mpLastStatusMessage ||
(*mpLastStatusMessage != *mpStatusMessage)) {
LOG_EVT_INFO(gEvtLog) << *mpStatusMessage;
// update the last status message
mpLastStatusMessage = std::make_unique<
StatusMessage>(*mpStatusMessage);
}
mpStatusMessage->incrementSequenceCounter();
} else {
LOG_EVT_ERROR(gEvtLog)
<< "unexpected datagram sent: size ["
<< bytes_transferred << "] bytes";
}
} else {
LOG_EVT_ERROR(gEvtLog) << "handle_send: asio error code["
<< error.value() << "]";
}
}
Aucun commentaire:
Enregistrer un commentaire