xo-alloc/xo-websock/include/xo/websock/Webserver.hpp
Roland Conybeare dd1a6b1afc Add 'xo-websock/' from commit '57bf06a68f'
git-subtree-dir: xo-websock
git-subtree-mainline: 97eefaea22
git-subtree-split: 57bf06a68f
2025-05-11 15:08:51 -05:00

116 lines
4.4 KiB
C++

/* @file Webserver.hpp */
#pragma once
#include "xo/refcnt/Displayable.hpp"
#include "xo/printjson/PrintJson.hpp"
#include "xo/webutil/HttpEndpointDescr.hpp"
#include "xo/webutil/StreamEndpointDescr.hpp"
#include <libwebsockets.h> // temporary, while moving callbacks
#include <thread>
#include <vector>
#include <memory>
namespace xo {
namespace web {
enum class Runstate { stopped, stop_requested, running };
class RunstateUtil {
public:
static char const * runstate_descr(Runstate x);
}; /*RunstateUtil*/
inline std::ostream & operator<<(std::ostream &os, Runstate x) {
os << RunstateUtil::runstate_descr(x);
return os;
} /*operator<<*/
class WebserverConfig {
public:
WebserverConfig() = default;
WebserverConfig(std::int32_t port,
bool tls_flag,
bool host_check_flag,
bool use_retry_flag)
: port_{port},
tls_flag_{tls_flag},
host_check_flag_{host_check_flag},
use_retry_flag_{use_retry_flag} {}
std::int32_t port() const { return port_; }
bool tls_flag() const { return tls_flag_; }
bool host_check_flag() const { return host_check_flag_; }
bool use_retry_flag() const { return use_retry_flag_; }
private:
/* accept incoming http requests on this port# */
std::int32_t port_ = 0;
/* if true, support https */
bool tls_flag_ = false;
/* see LWS_SERVER_OPTION_VHOST_UPG_STRICT_HOST_CHECK */
bool host_check_flag_ = false;
/* see lws_context_creation_info.retry_and_idle_policy */
bool use_retry_flag_ = false;
}; /*WebserverConfig*/
/* libwebsocket:
* 1. doesn't support multiple threads
* (actually, looks like it does on further examination)
* 2. doesn't expose listening ports etc (at least afaik);
* in other words it expects to take over application's main thread
*
* enforce this property by making webserver a singleton
*
* .state .start_webserver() .state
* +---------+ -------------------> +---------+
* | stopped | | running |
* +---------+ +---------+
* ^ |
* | | .stop_webserver()
* | |
* +----------------+ |
* | stop_requested | <------------------/
* +----------------+
*
*/
class Webserver : public ref::Displayable {
public:
using Alist = xo::web::Alist;
using PrintJson = xo::json::PrintJson;
public:
/* note: although webserver allows creating multiple instances,
* the underlying libwebsocket library is not advertised to be
* threadsafe
*/
static rp<Webserver> make(WebserverConfig const & ws_config,
rp<PrintJson> const & pjson);
/* current state */
virtual Runstate state() const = 0;
virtual void register_http_endpoint(HttpEndpointDescr const & endpoint) = 0;
virtual void register_stream_endpoint(StreamEndpointDescr const & endpoint) = 0;
/* start thread for this webserver; idempotent */
virtual void start_webserver() = 0;
/* stop thread for this webserver; suitable for calling
* from interrupt handler
*/
virtual void interrupt_stop_webserver() = 0;
/* stop thread for this webserver; idempotent */
virtual void stop_webserver() = 0;
/* wait until webserver thread stopped */
virtual void join_webserver() = 0;
/* send text to a websocket session identified by session_id */
virtual void send_text(uint32_t session_id,
std::string text) = 0;
// ----- Inherited from Displayable -----
virtual void display(std::ostream & os) const;
}; /*Webserver*/
} /*namespace web*/
} /*namespace xo*/
/* end Webserver.hpp */