NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.5: NDN, CCN, CCNx, content centric networks
API Documentation
telemetry_server.cpp
Go to the documentation of this file.
2 
3 #include <websocketpp/server.hpp>
4 
5 #include <fstream>
6 #include <iostream>
7 #include <set>
8 #include <streambuf>
9 #include <string>
10 
32 public:
35 
36  telemetry_server() : m_count(0) {
37  // set up access channels to only log interesting things
41 
42  // Initialize the Asio transport policy
43  m_endpoint.init_asio();
44 
45  // Bind the handlers we are using
46  using websocketpp::lib::placeholders::_1;
47  using websocketpp::lib::bind;
48  m_endpoint.set_open_handler(bind(&telemetry_server::on_open,this,_1));
49  m_endpoint.set_close_handler(bind(&telemetry_server::on_close,this,_1));
50  m_endpoint.set_http_handler(bind(&telemetry_server::on_http,this,_1));
51  }
52 
53  void run(std::string docroot, uint16_t port) {
54  std::stringstream ss;
55  ss << "Running telemetry server on port "<< port <<" using docroot=" << docroot;
56  m_endpoint.get_alog().write(websocketpp::log::alevel::app,ss.str());
57 
58  m_docroot = docroot;
59 
60  // listen on specified port
61  m_endpoint.listen(port);
62 
63  // Start the server accept loop
64  m_endpoint.start_accept();
65 
66  // Set the initial timer to start telemetry
67  set_timer();
68 
69  // Start the ASIO io_service run loop
70  try {
71  m_endpoint.run();
72  } catch (websocketpp::exception const & e) {
73  std::cout << e.what() << std::endl;
74  }
75  }
76 
77  void set_timer() {
78  m_timer = m_endpoint.set_timer(
79  1000,
80  websocketpp::lib::bind(
82  this,
83  websocketpp::lib::placeholders::_1
84  )
85  );
86  }
87 
88  void on_timer(websocketpp::lib::error_code const & ec) {
89  if (ec) {
90  // there was an error, stop telemetry
91  m_endpoint.get_alog().write(websocketpp::log::alevel::app,
92  "Timer Error: "+ec.message());
93  return;
94  }
95 
96  std::stringstream val;
97  val << "count is " << m_count++;
98 
99  // Broadcast count to all connections
100  con_list::iterator it;
101  for (it = m_connections.begin(); it != m_connections.end(); ++it) {
102  m_endpoint.send(*it,val.str(),websocketpp::frame::opcode::text);
103  }
104 
105  // set timer for next telemetry check
106  set_timer();
107  }
108 
109  void on_http(connection_hdl hdl) {
110  // Upgrade our connection handle to a full connection_ptr
111  server::connection_ptr con = m_endpoint.get_con_from_hdl(hdl);
112 
113  std::ifstream file;
114  std::string filename = con->get_resource();
115  std::string response;
116 
117  m_endpoint.get_alog().write(websocketpp::log::alevel::app,
118  "http request1: "+filename);
119 
120  if (filename == "/") {
121  filename = m_docroot+"index.html";
122  } else {
123  filename = m_docroot+filename.substr(1);
124  }
125 
126  m_endpoint.get_alog().write(websocketpp::log::alevel::app,
127  "http request2: "+filename);
128 
129  file.open(filename.c_str(), std::ios::in);
130  if (!file) {
131  // 404 error
132  std::stringstream ss;
133 
134  ss << "<!doctype html><html><head>"
135  << "<title>Error 404 (Resource not found)</title><body>"
136  << "<h1>Error 404</h1>"
137  << "<p>The requested URL " << filename << " was not found on this server.</p>"
138  << "</body></head></html>";
139 
140  con->set_body(ss.str());
142  return;
143  }
144 
145  file.seekg(0, std::ios::end);
146  response.reserve(file.tellg());
147  file.seekg(0, std::ios::beg);
148 
149  response.assign((std::istreambuf_iterator<char>(file)),
150  std::istreambuf_iterator<char>());
151 
152  con->set_body(response);
153  con->set_status(websocketpp::http::status_code::ok);
154  }
155 
156  void on_open(connection_hdl hdl) {
157  m_connections.insert(hdl);
158  }
159 
160  void on_close(connection_hdl hdl) {
161  m_connections.erase(hdl);
162  }
163 private:
164  typedef std::set<connection_hdl,std::owner_less<connection_hdl>> con_list;
165 
166  server m_endpoint;
167  con_list m_connections;
168  server::timer_ptr m_timer;
169 
170  std::string m_docroot;
171 
172  // Telemetry data
173  uint64_t m_count;
174 };
175 
176 int main(int argc, char* argv[]) {
178 
179  std::string docroot;
180  uint16_t port = 9002;
181 
182  if (argc == 1) {
183  std::cout << "Usage: telemetry_server [documentroot] [port]" << std::endl;
184  return 1;
185  }
186 
187  if (argc >= 2) {
188  docroot = std::string(argv[1]);
189  }
190 
191  if (argc >= 3) {
192  int i = atoi(argv[2]);
193  if (i <= 0 || i > 65535) {
194  std::cout << "invalid port" << std::endl;
195  return 1;
196  }
197 
198  port = uint16_t(i);
199  }
200 
201  s.run(docroot, port);
202  return 0;
203 }
static level const all
Special aggregate value representing "all levels".
Definition: levels.hpp:152
void set_open_handler(open_handler h)
Definition: endpoint.hpp:277
static level const app
Special channel for application specific logs. Not used by the library.
Definition: levels.hpp:143
void on_close(connection_hdl hdl)
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
connection_ptr get_con_from_hdl(connection_hdl hdl, lib::error_code &ec)
Retrieves a connection_ptr from a connection_hdl (exception free)
Definition: endpoint.hpp:643
void set_close_handler(close_handler h)
Definition: endpoint.hpp:282
void on_open(connection_hdl hdl)
websocketpp::server< websocketpp::config::asio > server
int main(int argc, char *argv[])
void on_http(connection_hdl hdl)
The telemetry server accepts connections and sends a message every second to each client containing a...
static level const access_core
Aggregate package representing the commonly used core access channels Connect, Disconnect, Fail, and HTTP.
Definition: levels.hpp:150
void start_accept(lib::error_code &ec)
Starts the server&#39;s async connection acceptance loop (exception free)
void set_access_channels(log::level channels)
Set Access logging channel.
Definition: endpoint.hpp:220
void run(std::string docroot, uint16_t port)
void set_http_handler(http_handler h)
Definition: endpoint.hpp:312
void on_timer(websocketpp::lib::error_code const &ec)
void clear_access_channels(log::level channels)
Clear Access logging channels.
Definition: endpoint.hpp:231
connection_type::ptr connection_ptr
Type of a shared pointer to the connections this server will create.
virtual char const * what() const
Definition: error.hpp:263
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)
websocketpp::connection_hdl connection_hdl