8 #include "iwebsocketclientendpoint.h"
9 #include "websocketmessage.h"
10 #include "websocketclient.h"
14 #include <nap/logger.h>
19 template<
typename config>
38 template<
typename config>
54 virtual void stop()
override;
112 std::vector<std::unique_ptr<WebSocketClientWrapper<config>>>
mClients;
145 std::shared_ptr<asio::ssl::context> onTLSInit(websocketpp::connection_hdl);
147 bool verifyCertificate(
const char * hostname,
bool preverified, asio::ssl::verify_context& ctx);
160 template<
typename config>
202 typename websocketpp::endpoint<websocketpp::connection<config>, config>::connection_ptr connection);
213 websocketpp::client<config>* mEndPoint =
nullptr;
215 std::atomic<bool> mOpen = {
false };
223 template<
typename config>
228 mAccessLogLevel = mLogConnectionUpdates ? websocketpp::log::alevel::all ^ websocketpp::log::alevel::frame_payload
229 : websocketpp::log::alevel::fail;
232 mEndPoint.clear_error_channels(websocketpp::log::elevel::all);
233 mEndPoint.set_error_channels(mLogLevel);
235 mEndPoint.clear_access_channels(websocketpp::log::alevel::all);
236 mEndPoint.set_access_channels(mAccessLogLevel);
239 std::error_code stdec;
240 mEndPoint.init_asio(stdec);
243 errorState.
fail(stdec.message());
250 template<
typename config>
255 assert(mClientTask.valid());
258 mEndPoint.stop_perpetual();
261 for (
auto& client : mClients)
264 if (!client->disconnect(error))
265 nap::Logger::error(error.toString());
277 template<
typename config>
284 mEndPoint.start_perpetual();
295 template<
typename config>
298 std::error_code stdec;
299 mEndPoint.send(connection.mConnection, message,
static_cast<wspp::OpCode>(code), stdec);
302 error.fail(stdec.message());
309 template<
typename config>
312 std::error_code stdec;
313 mEndPoint.send(connection.mConnection, payload, length,
static_cast<wspp::OpCode>(code), stdec);
316 error.fail(stdec.message());
323 template<
typename config>
331 template<
typename config>
335 std::error_code stdec;
336 auto client_connection = mEndPoint.get_connection(client.
mURI, stdec);
339 error.fail(stdec.message());
347 std::string binary_string;
348 if (!client.
mTicket->toBinaryString(binary_string, error))
352 client_connection->add_subprotocol(binary_string, stdec);
355 error.fail(stdec.message());
364 mClients.emplace_back(std::move(meta_client));
371 mEndPoint.connect(client_connection);
377 template<
typename config>
380 auto found_it = std::find_if(mClients.begin(), mClients.end(), [&](
const auto& it)
382 return it->mResource == &client;
385 if (found_it == mClients.end())
392 if (!(*found_it)->disconnect(error))
394 nap::Logger::error(error.toString());
396 mClients.erase(found_it);
400 template<
typename config>
402 mResource(&client), mEndPoint(&endPoint), mHandle(connection->get_handle())
405 connection->set_open_handler(std::bind(&WebSocketClientWrapper::onConnectionOpened,
this, std::placeholders::_1));
406 connection->set_close_handler(std::bind(&WebSocketClientWrapper::onConnectionClosed,
this, std::placeholders::_1));
407 connection->set_fail_handler(std::bind(&WebSocketClientWrapper::onConnectionFailed,
this, std::placeholders::_1));
410 connection->set_message_handler(std::bind(
411 &WebSocketClientWrapper::onMessageReceived,
this,
412 std::placeholders::_1, std::placeholders::_2));
416 template<
typename config>
417 void WebSocketClientWrapper<config>::onConnectionOpened(wspp::ConnectionHandle connection)
419 assert(mResource !=
nullptr);
420 mResource->connectionOpened();
425 template<
typename config>
426 void WebSocketClientWrapper<config>::onConnectionClosed(wspp::ConnectionHandle connection)
429 std::error_code stdec;
430 auto cptr = mEndPoint->get_con_from_hdl(connection, stdec);
433 assert(mResource !=
nullptr);
434 mResource->connectionClosed(stdec.value(), stdec.message());
439 template<
typename config>
440 void WebSocketClientWrapper<config>::onConnectionFailed(wspp::ConnectionHandle connection)
443 std::error_code stdec;
444 auto cptr = mEndPoint->get_con_from_hdl(connection, stdec);
447 assert(mResource !=
nullptr);
448 mResource->connectionFailed(stdec.value(), stdec.message());
453 template<
typename config>
454 void WebSocketClientWrapper<config>::onMessageReceived(wspp::ConnectionHandle connection, wspp::MessagePtr msg)
456 assert(mResource !=
nullptr);
457 mResource->messageReceived(WebSocketMessage(msg));
461 template<
typename config>
467 std::error_code stdec;
468 auto cptr = mEndPoint->get_con_from_hdl(mHandle, stdec);
472 error.fail(stdec.message());
477 cptr->set_open_handler(
nullptr);
478 cptr->set_close_handler(
nullptr);
479 cptr->set_fail_handler(
nullptr);
480 cptr->set_message_handler(
nullptr);
483 mEndPoint->close(mHandle, websocketpp::close::status::going_away,
"disconnected", stdec);
486 nap::Logger::error(stdec.message());
493 template<
typename config>