8#ifdef TTK_ENABLE_WEBSOCKETPP
9 this->server.set_error_channels(websocketpp::log::elevel::none);
10 this->server.set_access_channels(websocketpp::log::alevel::none);
12 this->server.set_reuse_addr(
true);
15 this->server.init_asio();
18 this->server.set_message_handler(bind(&WebSocketIO::on_message,
this,
19 websocketpp::lib::placeholders::_1,
20 websocketpp::lib::placeholders::_2));
21 this->server.set_open_handler(
22 bind(&WebSocketIO::on_open,
this, websocketpp::lib::placeholders::_1));
23 this->server.set_close_handler(
24 bind(&WebSocketIO::on_close,
this, websocketpp::lib::placeholders::_1));
27 this->
printErr(
"WebSocketIO requires websocketpp header only library!");
34 }
catch(
const std::exception &e) {
35 this->printErr(e.what());
39#ifdef TTK_ENABLE_WEBSOCKETPP
42 return this->server.is_listening();
46 return this->portNumber;
52 this->portNumber = PortNumber;
54 this->
printMsg(
"Starting Server at Port: " + std::to_string(this->portNumber),
58 this->server.listen(this->portNumber);
61 this->server.start_accept();
64 this->serverThread = thread([
this]() {
67 std::lock_guard<std::mutex> guard(this->mutex);
68 this->serverThreadRunning =
true;
72 std::lock_guard<std::mutex> guard(this->mutex);
73 this->serverThreadRunning =
false;
75 }
catch(websocketpp::exception
const &e) {
76 this->printErr(
"Unable to start server: " + std::string(e.what()));
79 this->serverThread.detach();
81 this->
printMsg(
"Starting Server at Port: " + std::to_string(this->portNumber),
92 if(this->server.is_listening()) {
95 this->server.stop_listening(this->ec);
97 this->printErr(this->ec.message());
107 std::lock_guard<std::mutex> guard(this->mutex);
108 for(con_list::iterator it = this->connections.begin();
109 it != this->connections.end(); ++it) {
110 this->server.close(*it, websocketpp::close::status::normal,
111 "Terminating connection ...", this->ec);
113 this->printErr(this->ec.message());
117 this->connections.clear();
123 std::lock_guard<std::mutex> guard(this->mutex);
124 nC = this->connections.size();
132 this->
printMsg(
"Terminating Server Thread", 0, 0,
140 std::lock_guard<std::mutex> guard(this->mutex);
141 con = this->serverThreadRunning;
144 this->
printMsg(
"Terminating Server Thread", 1, 0,
153 if(this->connections.size() > 0) {
155 *this->connections.begin(), msg, websocketpp::frame::opcode::text);
162 const void *data)
const {
163 if(this->connections.size() > 0) {
164 this->server.send(*this->connections.begin(), data, sizeInBytes,
165 websocketpp::frame::opcode::binary);
172 if(msg.binaryPayload !=
nullptr)
173 return this->sendBinary(msg.binaryPayloadSize, msg.binaryPayload);
175 return this->sendString(msg.stringPayload);
179 this->messageQueue.emplace_back(msg);
184 this->messageQueue.emplace_back(sizeInBytes, data);
188 this->messageQueue.emplace_back(msg);
192 this->messageQueue = std::list<Message>();
197 const size_t nRemainingMessages = this->messageQueue.size();
198 if(nRemainingMessages < 1) {
199 this->printWrn(
"Empty message queue.");
203 if(nRemainingMessages > 1) {
204 float progress = ((float)(this->nMessages - nRemainingMessages))
205 / ((
float)(this->nMessages - 1));
207 "Sending " + std::to_string(this->nMessages) +
" queued messages",
211 "Sending " + std::to_string(this->nMessages) +
" queued messages", 1,
212 this->msgTimer.getElapsedTime());
215 auto msg = this->messageQueue.front();
216 this->messageQueue.pop_front();
217 return this->sendMessage(msg);
221 this->nMessages = this->messageQueue.size() + 2;
224 "Sending " + std::to_string(this->nMessages) +
" queued messages", 0, 0,
226 if(this->nMessages < 1) {
227 this->printWrn(
"Empty message list.");
231 this->messageQueue.emplace_front(
233 this->messageQueue.emplace_back(
236 return this->sendNextQueuedMessage();
240 const std::string &eventData) {
241 this->
printMsg(
"processEventBase:" + eventName +
" -> " + eventData,
244 if(eventName.compare(
"on_message") == 0) {
245 if(eventData.compare(
"ttk_WSIO_RequestNextMessage") == 0)
246 return this->sendNextQueuedMessage();
252int ttk::WebSocketIO::on_open(
const websocketpp::connection_hdl &hdl) {
253 std::lock_guard<std::mutex> lock(this->mutex);
259 if(!this->connections.empty()) {
260 this->printErr(
"One client is already connected.");
261 this->server.close(hdl, websocketpp::close::status::normal,
262 "Terminating connection ...", ec);
266 this->connections.insert(hdl);
269 this->processEvent(
"on_open");
274int ttk::WebSocketIO::on_close(
const websocketpp::connection_hdl &hdl) {
275 std::lock_guard<std::mutex> lock(this->mutex);
279 this->connections.erase(hdl);
285int ttk::WebSocketIO::on_message(
286 const websocketpp::connection_hdl &
ttkNotUsed(hdl),
287 const WSServer::message_ptr &msg) {
289 const auto &eventData = msg->get_payload();
290 if(eventData.rfind(
"ttk_WSIO_", 9) != 0)
291 this->
printMsg(
"Custom Message Received", 1, 0);
292 this->processEvent(
"on_message", eventData);
#define ttkNotUsed(x)
Mark function/method parameters that are not used in the function body at all.
void setDebugMsgPrefix(const std::string &prefix)
int printErr(const std::string &msg, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cerr) const
int sendNextQueuedMessage()
int sendString(const std::string &msg) const
int sendMessage(const Message &msg) const
int queueMessage(const std::string &msg)
int sendBinary(const size_t &sizeInBytes, const void *data) const
int processMessageQueue()
virtual int processEvent(const std::string &eventName, const std::string &eventData="")
int startServer(int PortNumber)
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/|__ _|"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)