Branch data Line data Source code
1 : : #include "util/WebSocketServer.hpp" 2 : : 3 : : 4 : : namespace ip = boost::asio::ip; 5 : : namespace ws = boost::beast::websocket; 6 : : 7 : : 8 : : using namespace m; 9 : : using namespace std::chrono_literals; 10 : : 11 : : 12 : : /*====================================================================================================================== 13 : : * WebSocketServer 14 : : *====================================================================================================================*/ 15 : : 16 : 0 : WebSocketServer::WebSocketServer(uint16_t port, on_message_t on_message) 17 : 0 : : io_ctx_(/* concurrency_level= */ 1) 18 [ # # # # ]: 0 : , acceptor_(io_ctx_, { ip::make_address("127.0.0.1"), port }) 19 [ # # ]: 0 : , on_message_(on_message) 20 : 0 : , port_(port) 21 : 0 : { } 22 : : 23 : 0 : WebSocketServer::Connection WebSocketServer::await() 24 : : { 25 : 0 : ip::tcp::socket socket(io_ctx_); 26 [ # # ]: 0 : acceptor_.accept(socket); 27 [ # # # # ]: 0 : return Connection(*this, std::make_unique<web_socket_t>(std::move(socket))); 28 : 0 : } 29 : : 30 : : 31 : : /*====================================================================================================================== 32 : 0 : * WebSocketServer::Connection 33 : : *====================================================================================================================*/ 34 : : 35 : 0 : WebSocketServer::Connection::Connection(WebSocketServer &server, std::unique_ptr<web_socket_t> ws) 36 : 0 : : server_(server) 37 : 0 : , ws_(std::move(ws)) 38 : 0 : { } 39 : : 40 : 0 : void WebSocketServer::Connection::send(std::string_view msg) 41 : : { 42 : 0 : ws_->text(ws_->got_text()); 43 : 0 : ws_->write(boost::asio::buffer(msg.data(), msg.length())); 44 : 0 : } 45 : : 46 : 0 : void WebSocketServer::Connection::listen() 47 : : { 48 : 0 : boost::beast::multi_buffer buffer; 49 [ # # ]: 0 : ws_->accept(); 50 : 0 : for (;;) { 51 : : try { 52 : 0 : buffer.clear(); 53 [ # # # # ]: 0 : if (ws_->read(buffer) == 0) 54 : 0 : return; 55 [ # # ]: 0 : } catch (const boost::system::system_error &e) { 56 : 0 : const auto ec = e.code(); 57 [ # # ]: 0 : if (ec == ws::error::closed) 58 : : return; 59 : : else 60 [ # # ]: 0 : throw; 61 [ # # # # ]: 0 : } 62 [ # # ]: 0 : std::string msg = boost::beast::buffers_to_string(buffer.data()); 63 [ # # # # : 0 : server().on_message(msg); # # ] 64 : 0 : } 65 : 0 : } 66 : : 67 : 0 : bool WebSocketServer::Connection::wait_on_message() 68 : : { 69 : 0 : boost::beast::multi_buffer buffer; 70 : : try { 71 : 0 : buffer.clear(); 72 [ # # # # ]: 0 : if (ws_->read(buffer) == 0) 73 : 0 : return false; 74 [ # # ]: 0 : } catch (const boost::system::system_error &e) { 75 : 0 : const auto ec = e.code(); 76 [ # # ]: 0 : if (ec == ws::error::closed) 77 : 0 : return false; 78 : : else 79 [ # # ]: 0 : throw; 80 [ # # # # ]: 0 : } 81 [ # # ]: 0 : std::string msg = boost::beast::buffers_to_string(buffer.data()); 82 [ # # # # : 0 : server().on_message(msg); # # ] 83 : 0 : return true; 84 : 0 : }