#include "websocket_client.h" // This message handler will be invoked once for each incoming message. It // prints the message and then sends a copy of the message back to the server. void on_message(WebsocketClient* c, websocketpp::connection_hdl hdl, message_ptr msg) { std::cout << "on_message called with hdl: " << hdl.lock().get() << " and message: " << msg->get_payload() << std::endl; websocketpp::lib::error_code ec; // c->send(hdl, msg->get_payload(), msg->get_opcode(), ec); if (ec) { std::cout << "Echo failed because: " << ec.message() << std::endl; } if (c->m_onread != nullptr) { c->m_onread(c, msg->get_payload()); } } int WebsocketClient::SendMsg(const char* str, uint32_t len, websocketpp::frame::opcode::value opcode) { if (this->m_status != WebsocketClient::CONNECTED) return -1; if (m_tls) { websocketpp::lib::error_code ec; this->m_client_tls.send(m_conn_tls, str, len, opcode, ec); if (ec) { std::cout << "Echo failed because: " << ec.message() << std::endl; return -1; } } else { websocketpp::lib::error_code ec; this->m_client.send(m_conn, str, len, opcode, ec); if (ec) { std::cout << "Echo failed because: " << ec.message() << std::endl; return -1; } } return 0; } void on_open(WebsocketClient* c, websocketpp::connection_hdl hdl) { if (c->m_tls) { TlsClient::connection_ptr con = c->m_client_tls.get_con_from_hdl(hdl); uint32_t usocket = con->get_raw_socket().native_handle(); auto m_server = con->get_response_header("Server"); std::cout << "open from server" << m_server << std::endl; c->m_status = WebsocketClient::CONNECTED; if (c->m_on_connected != nullptr) { c->m_on_connected(c); } } else { Client::connection_ptr con = c->m_client.get_con_from_hdl(hdl); uint32_t usocket = con->get_raw_socket().native_handle(); auto m_server = con->get_response_header("Server"); std::cout << "open from server" << m_server << std::endl; c->m_status = WebsocketClient::CONNECTED; if (c->m_on_connected != nullptr) { c->m_on_connected(c); } } } void on_close(WebsocketClient* c, websocketpp::connection_hdl hdl) { // m_status = "Open"; // client::connection_ptr con = c->get_con_from_hdl(hdl); // m_server = con->get_response_header("Server"); c->m_status = WebsocketClient::CLOSED; std::cout << "on_close" << std::endl; if (c->m_on_disconnected != nullptr) { c->m_on_disconnected(c, WebsocketClient::CloseReason::LOCAL_CLOSED); } } void on_fail(WebsocketClient* c, websocketpp::connection_hdl hdl) { std::cout << "on_fail" << std::endl; Client::connection_ptr con = c->m_client.get_con_from_hdl(hdl); auto state = con->get_state(); if (state == websocketpp::session::state::closed) std::cout << state << " on_fail " << std::endl; c->m_status = WebsocketClient::FAIL; if (c->m_on_disconnected != nullptr) { c->m_on_disconnected(c, WebsocketClient::CloseReason::PEER_CLOSED); } } WebsocketClient::~WebsocketClient() { this->m_status = WebsocketClient::STOP; m_client.stop(); m_thread->join(); } WebsocketClient::WebsocketClient(std::string url, bool tls) { m_tls = tls; m_auto_reconn = false; m_url = url; this->m_status = WebsocketClient::CONNECTING; if (m_tls) { // Set logging to be pretty verbose (everything except message payloads) m_client_tls.set_access_channels(websocketpp::log::alevel::all); m_client_tls.clear_access_channels(websocketpp::log::alevel::frame_payload); m_client_tls.set_tls_init_handler([this](websocketpp::connection_hdl) { return websocketpp::lib::make_shared(asio::ssl::context::tlsv1); }); // Initialize ASIO m_client_tls.init_asio(); m_thread = new std::thread([this]() { while (this->m_status != STOP) { m_client_tls.set_message_handler(bind(&on_message, this, ::_1, ::_2)); websocketpp::lib::error_code ec; std::cout << "1" << std::endl; m_conn_tls = m_client_tls.get_connection(this->m_url, ec); m_conn_tls->set_open_handler(websocketpp::lib::bind( &on_open, this, websocketpp::lib::placeholders::_1 )); m_conn_tls->set_fail_handler(websocketpp::lib::bind( &on_fail, this, websocketpp::lib::placeholders::_1 )); m_conn_tls->set_close_handler(websocketpp::lib::bind( &on_close, this, websocketpp::lib::placeholders::_1 )); if (ec) { std::cout << "could not create connection because: " << ec.message() << std::endl; this->m_status = Status::FAIL; } std::cout << "2" << std::endl; // Note that connect here only requests a connection. No network messages are // exchanged until the event loop starts running in the next line. TlsClient::connection_ptr ptr = m_client_tls.connect(m_conn_tls); if (ptr->get_state() != websocketpp::session::state::open) std::cout << ptr->get_state() << " websocketpp::session::state " << std::endl; // Start the ASIO io_service run loop // this will cause a single connection to be made to the server. c.run() // will exit when this connection is closed. std::cout << "3 " << ptr << " " << m_conn_tls << std::endl; this->m_status = WebsocketClient::CONNECTING; while ((this->m_status != WebsocketClient::FAIL) && (this->m_status != WebsocketClient::CLOSED) && (this->m_status != WebsocketClient::STOP) ) { try { // while(this->m_status == WebsocketClient::CONNECTED){ int count_of_handler = this->m_client_tls.run(); // std::cout<<"count_of_handler: " << count_of_handler<m_on_disconnected(this, WebsocketClient::CloseReason::LOCAL_CLOSED); }); } else { // Set logging to be pretty verbose (everything except message payloads) m_client.set_access_channels(websocketpp::log::alevel::all); m_client.clear_access_channels(websocketpp::log::alevel::frame_payload); // Initialize ASIO this->m_client.init_asio(); m_thread = new std::thread([this]() { while (this->m_status != STOP) { this->m_client.set_message_handler(bind(&on_message, this, ::_1, ::_2)); websocketpp::lib::error_code ec; std::cout << "1" << std::endl; m_conn = m_client.get_connection(this->m_url, ec); if (m_conn != nullptr) { m_conn->set_open_handler(websocketpp::lib::bind( &on_open, this, websocketpp::lib::placeholders::_1 )); m_conn->set_fail_handler(websocketpp::lib::bind( &on_fail, this, websocketpp::lib::placeholders::_1 )); m_conn->set_close_handler(websocketpp::lib::bind( &on_close, this, websocketpp::lib::placeholders::_1 )); } if (ec) { std::cout << "could not create connection because: " << ec.message() << std::endl; this->m_status = Status::FAIL; if (m_on_disconnected) m_on_disconnected(this, WebsocketClient::CloseReason::LOCAL_CLOSED); break; } std::cout << "2" << std::endl; // Note that connect here only requests a connection. No network messages are // exchanged until the event loop starts running in the next line. Client::connection_ptr ptr = this->m_client.connect(m_conn); if (ptr->get_state() != websocketpp::session::state::open) std::cout << ptr->get_state() << " websocketpp::session::state " << std::endl; // Start the ASIO io_service run loop // this will cause a single connection to be made to the server. c.run() // will exit when this connection is closed. std::cout << "3 " << ptr << " " << m_conn_tls << std::endl; this->m_status = WebsocketClient::CONNECTING; while ((this->m_status != WebsocketClient::FAIL) && (this->m_status != WebsocketClient::CLOSED) && (this->m_status != WebsocketClient::STOP) ) { try { // while(this->m_status == WebsocketClient::CONNECTED){ int count_of_handler = this->m_client.run(); // std::cout<<"count_of_handler: " << count_of_handler<m_on_connected = on_connected; return 0; } int WebsocketClient::SetOnDisConnectedHandler(OnDisConnectedHandler on_disconnected) { this->m_on_disconnected = on_disconnected; return 0; } int WebsocketClient::SetOnReadHandler(OnReadHandler onread) { this->m_onread = onread; return 0; }