// Copyright (c) 2021 hiimgoodpack // Permission is hereby granted, free of charge, to any person obtaining a copy of // this software and associated documentation files (the "Software"), to deal in // the Software without restriction, including without limitation the rights to // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is furnished to do // so, subject to the following conditions: // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #ifndef WEBSOCKET_H #define WEBSOCKET_H #include #include #include // We're doing some declarations instead of just including all of websocketpp since // websocketpp takes a long time to compile #include #include class WebSocketError : public std::runtime_error { public: using runtime_error::runtime_error; }; class WebSocket : public websocketpp::lib::asio::io_service { private: websocketpp::client client; websocketpp::connection_hdl hdl; static void onConnectHandler(WebSocket*, websocketpp::connection_hdl); static void onReceiveHandler(WebSocket*, websocketpp::config::asio_client::message_type::ptr); static void onCloseHandler(WebSocket*); public: WebSocket(const std::string& url); void send(std::string buffer); void close(); std::function onConnect = nullptr; std::function onReceive = nullptr; std::function onClose = nullptr; }; #endif #if defined(WEBSOCKET_IMPLEMENTATION) && !defined(WEBSOCKET_IMPLEMENTED) #define WEBSOCKET_IMPLEMENTED #include #include WebSocket::WebSocket(const std::string& url) { client.clear_access_channels(websocketpp::log::alevel::all); client.clear_error_channels(websocketpp::log::elevel::all); client.init_asio(reinterpret_cast(this)); client.set_open_handler(std::bind(onConnectHandler, this, std::placeholders::_1)); client.set_message_handler(std::bind(onReceiveHandler, this, std::placeholders::_2)); client.set_close_handler(std::bind(onCloseHandler, this)); websocketpp::lib::error_code error; decltype(client)::connection_ptr connection = client.get_connection(url, error); if (error) throw WebSocketError(error.message()); client.connect(connection); } void WebSocket::onConnectHandler(WebSocket* socket, websocketpp::connection_hdl hdl) { socket->hdl = hdl; if (socket->onConnect) socket->onConnect(); } void WebSocket::onReceiveHandler(WebSocket* socket, websocketpp::config::asio_client::message_type::ptr message) { std::cerr << "Received: " << message->get_payload() << "\n"; if (socket->onReceive) socket->onReceive(message->get_payload()); } void WebSocket::onCloseHandler(WebSocket* socket) { if (socket->onClose) socket->onClose(); } void WebSocket::send(std::string buffer) { std::cerr << "Sending: " << buffer << "\n"; client.send(hdl, buffer, websocketpp::frame::opcode::text); } void WebSocket::close() { client.close(hdl, websocketpp::close::status::going_away, ""); } #endif