LCOV - code coverage report
Current view: top level - app/src/Com - WebSocketServer.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 46 0.0 %
Date: 2023-08-17 16:45:52 Functions: 0 5 0.0 %

          Line data    Source code
       1             : #include "Com/WebSocketServer.hpp"
       2             : 
       3             : #include <spdlog/spdlog.h>
       4             : 
       5             : #include <websocketpp/close.hpp>
       6             : 
       7             : #include "GlobalState.hpp"
       8             : #include "utils/string.hpp"
       9             : 
      10             : using namespace std;
      11             : using namespace Com;
      12             : 
      13             : typedef websocketpp::server<websocketpp::config::asio> server;
      14             : typedef server::message_ptr                            message_ptr;
      15             : 
      16             : using websocketpp::lib::bind;
      17             : using websocketpp::lib::placeholders::_1;
      18             : 
      19             : typedef websocketpp::log::alevel alevel;
      20             : 
      21           0 : WebSocketServer::WebSocketServer(int port) {
      22             :     // From https://github.com/zaphoyd/websocketpp/blob/master/examples/echo_server/echo_server.cpp
      23           0 :     try {
      24           0 :         spdlog::info("Starting WebSockets server");
      25             : 
      26             :         // Set logging settings
      27           0 :         srv.set_access_channels(alevel::all);
      28           0 :         srv.clear_access_channels(alevel::frame_header | alevel::frame_payload);
      29             : 
      30             :         // Initialize Asio
      31           0 :         srv.init_asio();
      32             : 
      33             :         // Register our message handler
      34           0 :         srv.set_open_handler(bind(&WebSocketServer::wsHandler, this, ::_1));
      35             : 
      36             :         // Listen on port 9001
      37           0 :         srv.listen((uint16_t)port);
      38             : 
      39             :         // Start the server accept loop
      40           0 :         srv.start_accept();
      41             : 
      42           0 :         spdlog::info("Started WebSockets server");
      43           0 :     } catch(const exception &e) {
      44           0 :         spdlog::error("Exception, what(): {}", e.what());
      45             :     }
      46           0 : }
      47             : 
      48           0 : void WebSocketServer::loop() {
      49             :     // Start the ASIO io_service run loop
      50           0 :     srv.run();
      51           0 : }
      52             : 
      53           0 : void WebSocketServer::wsHandler(websocketpp::connection_hdl hdl) {
      54           0 :     thread t(&WebSocketServer::wsHandlerThread, this, hdl);
      55           0 :     t.detach();
      56           0 : }
      57             : 
      58           0 : void WebSocketServer::wsHandlerThread(websocketpp::connection_hdl hdl) {
      59           0 :     try {
      60           0 :         wsStringStream(hdl);
      61           0 :     } catch(const exception &e) {
      62           0 :         spdlog::error("Exception, what(): {}", e.what());
      63             :     }
      64           0 : }
      65             : 
      66           0 : void WebSocketServer::wsStringStream(websocketpp::connection_hdl hdl) {
      67             :     // From https://stackoverflow.com/questions/30514362/handle-websocketpp-connection-path
      68           0 :     server::connection_ptr con = srv.get_con_from_hdl(hdl);
      69             : 
      70           0 :     const string postfix = "/log";
      71             : 
      72           0 :     const string &resource = con->get_resource();
      73           0 :     assert(utils::ends_with(resource, postfix));
      74           0 :     const string resourceID = resource.substr(0, resource.size() - postfix.size());
      75           0 :     const string streamID   = "stream://" + resourceID;
      76             : 
      77           0 :     try {
      78           0 :         utils::pipestream &ios = GlobalState::streams.get(streamID);
      79           0 :         istream           &is  = ios.i();
      80             : 
      81           0 :         string payload;
      82           0 :         while(getline(is, payload)) {
      83           0 :             srv.send(hdl, payload, websocketpp::frame::opcode::binary);
      84             :         }
      85           0 :     } catch(const GlobalState::ResourceException &e) {
      86           0 :         srv.close(hdl, websocketpp::close::status::internal_endpoint_error, e.what());
      87           0 :         return;
      88           0 :     } catch(const iostream::failure &e) {
      89           0 :         spdlog::error("Exception reading pipestream, what(): {}", e.what());
      90           0 :         srv.close(hdl, websocketpp::close::status::internal_endpoint_error, "Exception, what(): "s + e.what());
      91             :     }
      92             : 
      93           0 :     srv.close(hdl, websocketpp::close::status::normal, "EOF");
      94             : }

Generated by: LCOV version 1.14