Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
telemetry_server.cpp
Go to the documentation of this file.
2
4
5#include <fstream>
6#include <iostream>
7#include <set>
8#include <streambuf>
9#include <string>
10
32public:
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
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
157 m_connections.insert(hdl);
158 }
159
161 m_connections.erase(hdl);
162 }
163private:
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
176int 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}
void on_open(connection_hdl hdl)
websocketpp::connection_hdl connection_hdl
void run(std::string docroot, uint16_t port)
websocketpp::server< websocketpp::config::asio > server
void on_close(connection_hdl hdl)
void on_http(connection_hdl hdl)
void on_timer(websocketpp::lib::error_code const &ec)
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
alog_type & get_alog()
Get reference to access logger.
Definition endpoint.hpp:261
void clear_access_channels(log::level channels)
Clear Access logging channels.
Definition endpoint.hpp:231
void set_http_handler(http_handler h)
Definition endpoint.hpp:312
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)
void set_open_handler(open_handler h)
Definition endpoint.hpp:277
void set_access_channels(log::level channels)
Set Access logging channel.
Definition endpoint.hpp:220
void set_close_handler(close_handler h)
Definition endpoint.hpp:282
virtual char const * what() const
Definition error.hpp:263
Server endpoint role based on the given config.
void start_accept(lib::error_code &ec)
Starts the server's async connection acceptance loop (exception free)
char ** argv
lib::weak_ptr< void > connection_hdl
A handle to uniquely identify a connection.
unsigned short uint16_t
Definition stdint.h:125
unsigned __int64 uint64_t
Definition stdint.h:136
static level const all
Special aggregate value representing "all levels".
Definition levels.hpp:152
static level const app
Special channel for application specific logs. Not used by the library.
Definition levels.hpp:143
static level const access_core
Definition levels.hpp:150
char * s