notification-subscriber.hpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2014-2024 Regents of the University of California,
4  * Arizona Board of Regents,
5  * Colorado State University,
6  * University Pierre & Marie Curie, Sorbonne University,
7  * Washington University in St. Louis,
8  * Beijing Institute of Technology,
9  * The University of Memphis.
10  *
11  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
12  *
13  * ndn-cxx library is free software: you can redistribute it and/or modify it under the
14  * terms of the GNU Lesser General Public License as published by the Free Software
15  * Foundation, either version 3 of the License, or (at your option) any later version.
16  *
17  * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
18  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
19  * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
20  *
21  * You should have received copies of the GNU General Public License and GNU Lesser
22  * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
23  * <http://www.gnu.org/licenses/>.
24  *
25  * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
26  */
27 
28 #ifndef NDN_CXX_UTIL_NOTIFICATION_SUBSCRIBER_HPP
29 #define NDN_CXX_UTIL_NOTIFICATION_SUBSCRIBER_HPP
30 
31 #include "ndn-cxx/face.hpp"
35 #include "ndn-cxx/util/time.hpp"
36 
37 namespace ndn::util {
38 
39 class NotificationSubscriberBase : noncopyable
40 {
41 public:
42  virtual
44 
52  {
53  return m_interestLifetime;
54  }
55 
56  bool
57  isRunning() const
58  {
59  return m_isRunning;
60  }
61 
66  void
67  start();
68 
71  void
72  stop();
73 
74 protected:
79  NotificationSubscriberBase(Face& face, const Name& prefix,
80  time::milliseconds interestLifetime);
81 
82 private:
87  bool
88  shouldStop();
89 
90  void
91  sendInitialInterest();
92 
93  void
94  sendNextInterest();
95 
96  void
97  sendInterest(const Interest& interest);
98 
99  virtual bool
100  hasSubscriber() const = 0;
101 
102  void
103  afterReceiveData(const Data& data);
104 
108  virtual bool
109  decodeAndDeliver(const Data& data) = 0;
110 
111  void
112  afterReceiveNack(const lp::Nack& nack);
113 
114  void
115  afterTimeout();
116 
118  exponentialBackoff(const lp::Nack& nack);
119 
120 public:
123 
126 
129 
130 private:
131  Face& m_face;
132  Name m_prefix;
133  uint64_t m_lastSequenceNum = std::numeric_limits<uint64_t>::max();
134  uint64_t m_lastNackSequenceNum = std::numeric_limits<uint64_t>::max();
135  uint64_t m_attempts = 1;
136  Scheduler m_scheduler;
137  scheduler::ScopedEventId m_nackEvent;
138  ScopedPendingInterestHandle m_lastInterest;
139  time::milliseconds m_interestLifetime;
140  bool m_isRunning = false;
141 };
142 
148 template<typename Notification>
150 {
151 public:
152  BOOST_CONCEPT_ASSERT((boost::DefaultConstructible<Notification>));
153  BOOST_CONCEPT_ASSERT((WireDecodable<Notification>));
154 
159  NotificationSubscriber(Face& face, const Name& prefix,
160  time::milliseconds interestLifetime = 1_min)
161  : NotificationSubscriberBase(face, prefix, interestLifetime)
162  {
163  }
164 
165 public:
171 
172 private:
173  bool
174  hasSubscriber() const override
175  {
176  return !onNotification.isEmpty();
177  }
178 
179  bool
180  decodeAndDeliver(const Data& data) override
181  {
182  Notification notification;
183  try {
184  notification.wireDecode(data.getContent().blockFromValue());
185  }
186  catch (const tlv::Error&) {
187  return false;
188  }
189  onNotification(notification);
190  return true;
191  }
192 };
193 
194 } // namespace ndn::util
195 
196 #endif // NDN_CXX_UTIL_NOTIFICATION_SUBSCRIBER_HPP
Block blockFromValue() const
Return a new Block constructed from the TLV-VALUE of this Block.
Definition: block.cpp:314
Represents a Data packet.
Definition: data.hpp:39
const Block & getContent() const noexcept
Get the Content element.
Definition: data.hpp:188
Provide a communication channel with local or remote NDN forwarder.
Definition: face.hpp:91
Represents an Interest packet.
Definition: interest.hpp:50
Represents an absolute name.
Definition: name.hpp:45
A concept check for TLV abstraction with a wireDecode(Block) method and constructible from Block.
Definition: concepts.hpp:82
Represents a Network Nack.
Definition: nack.hpp:39
Generic time-based event scheduler.
Definition: scheduler.hpp:138
Provides a lightweight signal / event system.
Definition: signal.hpp:51
Represents an error in TLV encoding or decoding.
Definition: tlv.hpp:54
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.
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.
Provides the subscriber side of a Notification Stream.
NotificationSubscriber(Face &face, const Name &prefix, time::milliseconds interestLifetime=1_min)
Construct a NotificationSubscriber.
ndn::signal::Signal< NotificationSubscriber, Notification > onNotification
Fires when a Notification is received.
::boost::chrono::milliseconds milliseconds
Definition: time.hpp:52