NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.5: NDN, CCN, CCNx, content centric networks
API Documentation
telemetry_client.cpp
Go to the documentation of this file.
2 #include <websocketpp/client.hpp>
3 
4 // This header pulls in the WebSocket++ abstracted thread support that will
5 // select between boost::thread and std::thread based on how the build system
6 // is configured.
8 
12 void wait_a_bit() {
13 #ifdef WIN32
14  Sleep(1000);
15 #else
16  sleep(1);
17 #endif
18 }
19 
27 public:
29  typedef websocketpp::lib::lock_guard<websocketpp::lib::mutex> scoped_lock;
30 
31  telemetry_client() : m_open(false),m_done(false) {
32  // set up access channels to only log interesting things
37 
38  // Initialize the Asio transport policy
39  m_client.init_asio();
40 
41  // Bind the handlers we are using
42  using websocketpp::lib::placeholders::_1;
43  using websocketpp::lib::bind;
44  m_client.set_open_handler(bind(&telemetry_client::on_open,this,_1));
45  m_client.set_close_handler(bind(&telemetry_client::on_close,this,_1));
46  m_client.set_fail_handler(bind(&telemetry_client::on_fail,this,_1));
47  }
48 
49  // This method will block until the connection is complete
50  void run(const std::string & uri) {
51  // Create a new connection to the given URI
52  websocketpp::lib::error_code ec;
53  client::connection_ptr con = m_client.get_connection(uri, ec);
54  if (ec) {
55  m_client.get_alog().write(websocketpp::log::alevel::app,
56  "Get Connection Error: "+ec.message());
57  return;
58  }
59 
60  // Grab a handle for this connection so we can talk to it in a thread
61  // safe manor after the event loop starts.
62  m_hdl = con->get_handle();
63 
64  // Queue the connection. No DNS queries or network connections will be
65  // made until the io_service event loop is run.
66  m_client.connect(con);
67 
68  // Create a thread to run the ASIO io_service event loop
69  websocketpp::lib::thread asio_thread(&client::run, &m_client);
70 
71  // Create a thread to run the telemetry loop
72  websocketpp::lib::thread telemetry_thread(&telemetry_client::telemetry_loop,this);
73 
74  asio_thread.join();
75  telemetry_thread.join();
76  }
77 
78  // The open handler will signal that we are ready to start sending telemetry
80  m_client.get_alog().write(websocketpp::log::alevel::app,
81  "Connection opened, starting telemetry!");
82 
83  scoped_lock guard(m_lock);
84  m_open = true;
85  }
86 
87  // The close handler will signal that we should stop sending telemetry
89  m_client.get_alog().write(websocketpp::log::alevel::app,
90  "Connection closed, stopping telemetry!");
91 
92  scoped_lock guard(m_lock);
93  m_done = true;
94  }
95 
96  // The fail handler will signal that we should stop sending telemetry
98  m_client.get_alog().write(websocketpp::log::alevel::app,
99  "Connection failed, stopping telemetry!");
100 
101  scoped_lock guard(m_lock);
102  m_done = true;
103  }
104 
105  void telemetry_loop() {
106  uint64_t count = 0;
107  std::stringstream val;
108  websocketpp::lib::error_code ec;
109 
110  while(1) {
111  bool wait = false;
112 
113  {
114  scoped_lock guard(m_lock);
115  // If the connection has been closed, stop generating telemetry
116  if (m_done) {break;}
117 
118  // If the connection hasn't been opened yet wait a bit and retry
119  if (!m_open) {
120  wait = true;
121  }
122  }
123 
124  if (wait) {
125  wait_a_bit();
126  continue;
127  }
128 
129  val.str("");
130  val << "count is " << count++;
131 
132  m_client.get_alog().write(websocketpp::log::alevel::app, val.str());
133  m_client.send(m_hdl,val.str(),websocketpp::frame::opcode::text,ec);
134 
135  // The most likely error that we will get is that the connection is
136  // not in the right state. Usually this means we tried to send a
137  // message to a connection that was closed or in the process of
138  // closing. While many errors here can be easily recovered from,
139  // in this simple example, we'll stop the telemetry loop.
140  if (ec) {
141  m_client.get_alog().write(websocketpp::log::alevel::app,
142  "Send Error: "+ec.message());
143  break;
144  }
145 
146  wait_a_bit();
147  }
148  }
149 private:
150  client m_client;
152  websocketpp::lib::mutex m_lock;
153  bool m_open;
154  bool m_done;
155 };
156 
157 int main(int argc, char* argv[]) {
159 
160  std::string uri = "ws://localhost:9002";
161 
162  if (argc == 2) {
163  uri = argv[1];
164  }
165 
166  c.run(uri);
167 }
static level const all
Special aggregate value representing "all levels".
Definition: levels.hpp:152
connection_type::ptr connection_ptr
Type of a shared pointer to the connections this server will create.
websocketpp::lib::lock_guard< websocketpp::lib::mutex > scoped_lock
websocketpp::client< websocketpp::config::asio_client > client
void set_open_handler(open_handler h)
Definition: endpoint.hpp:277
void wait_a_bit()
Define a semi-cross platform helper method that waits/sleeps for a bit.
static level const app
Special channel for application specific logs. Not used by the library.
Definition: levels.hpp:143
lib::weak_ptr< void > connection_hdl
A handle to uniquely identify a connection.
alog_type & get_alog()
Get reference to access logger.
Definition: endpoint.hpp:261
void on_open(websocketpp::connection_hdl)
void set_close_handler(close_handler h)
Definition: endpoint.hpp:282
The telemetry client connects to a WebSocket server and sends a message every second containing an in...
connection_ptr connect(connection_ptr con)
Begin the connection process for the given connection.
void on_fail(websocketpp::connection_hdl)
static level const disconnect
One line for each closed connection. Includes closing codes and reasons.
Definition: levels.hpp:123
int main(int argc, char *argv[])
void set_access_channels(log::level channels)
Set Access logging channel.
Definition: endpoint.hpp:220
void run(const std::string &uri)
void set_fail_handler(fail_handler h)
Definition: endpoint.hpp:287
void clear_access_channels(log::level channels)
Clear Access logging channels.
Definition: endpoint.hpp:231
void on_close(websocketpp::connection_hdl)
void send(connection_hdl hdl, std::string const &payload, frame::opcode::value op, lib::error_code &ec)
Create a message and add it to the outgoing send queue (exception free)
connection_ptr get_connection(uri_ptr location, lib::error_code &ec)
Get a new connection.
static level const connect
Information about new connections.
Definition: levels.hpp:121