39 , m_scheduler(face.getIoContext())
40 , m_interestLifetime(interestLifetime)
53 sendInitialInterest();
67 NotificationSubscriberBase::sendInitialInterest()
72 auto interest = make_shared<Interest>(m_prefix);
73 interest->setCanBePrefix(
true);
74 interest->setMustBeFresh(
true);
75 interest->setInterestLifetime(m_interestLifetime);
76 sendInterest(*interest);
80 NotificationSubscriberBase::sendNextInterest()
85 Name nextName = m_prefix;
88 auto interest = make_shared<Interest>(nextName);
89 interest->setInterestLifetime(m_interestLifetime);
90 sendInterest(*interest);
94 NotificationSubscriberBase::sendInterest(
const Interest& interest)
97 [
this] (
const auto&,
const auto& d) { afterReceiveData(d); },
98 [
this] (
const auto&,
const auto& n) { afterReceiveNack(n); },
99 [
this] (
const auto&) { afterTimeout(); });
103 NotificationSubscriberBase::shouldStop()
108 if (!hasSubscriber() &&
onNack.isEmpty()) {
116 NotificationSubscriberBase::afterReceiveData(
const Data& data)
122 m_lastSequenceNum = data.getName().get(-1).toSequenceNumber();
124 catch (
const tlv::Error&) {
126 sendInitialInterest();
130 if (!decodeAndDeliver(data)) {
132 sendInitialInterest();
140 NotificationSubscriberBase::afterReceiveNack(
const lp::Nack& nack)
147 auto delay = exponentialBackoff(nack);
148 m_nackEvent = m_scheduler.
schedule(delay, [
this] { sendInitialInterest(); });
152 NotificationSubscriberBase::afterTimeout()
158 sendInitialInterest();
162 NotificationSubscriberBase::exponentialBackoff(
const lp::Nack& nack)
164 uint64_t nackSequenceNum = 0;
166 nackSequenceNum = nack.getInterest().getName().get(-1).toSequenceNumber();
168 catch (
const tlv::Error&) {
172 if (m_lastNackSequenceNum == nackSequenceNum) {
179 m_lastNackSequenceNum = nackSequenceNum;
181 return time::milliseconds(
static_cast<time::milliseconds::rep
>(std::pow(2, m_attempts) * 100 +
Provide a communication channel with local or remote NDN forwarder.
PendingInterestHandle expressInterest(const Interest &interest, const DataCallback &afterSatisfied, const NackCallback &afterNacked, const TimeoutCallback &afterTimeout)
Express an Interest.
Represents an absolute name.
Name & appendSequenceNumber(uint64_t seqNo)
Append a sequence number component.
void cancel()
Cancel the operation.
EventId schedule(time::nanoseconds after, EventCallback callback)
Schedule a one-time event after the specified delay.
void start()
Start or resume receiving notifications.
void stop()
Stop receiving notifications.
ndn::signal::Signal< NotificationSubscriberBase > onTimeout
Fires when no Notification is received within getInterestLifetime() period.
virtual ~NotificationSubscriberBase()
NotificationSubscriberBase(Face &face, const Name &prefix, time::milliseconds interestLifetime)
Construct a NotificationSubscriber.
ndn::signal::Signal< NotificationSubscriberBase, lp::Nack > onNack
Fires when a Nack is received.
ndn::signal::Signal< NotificationSubscriberBase, Data > onDecodeError
Fires when a Data packet in the notification stream cannot be decoded as a Notification.
uint32_t generateWord32()
Generate a non-cryptographically-secure random integer in the range [0, 2^32).
::boost::chrono::milliseconds milliseconds