#pragma once #include #include #include #include #include #include #include "utils/Json.h" #include "WebSocketSession.h" class WebSocketServer : QObject { Q_OBJECT public: enum WebSocketEncoding { Json, MsgPack }; struct WebSocketSessionState { websocketpp::connection_hdl hdl; std::string remoteAddress; uint64_t connectedAt; uint64_t incomingMessages; uint64_t outgoingMessages; bool isIdentified; }; enum WebSocketOpCode { Hello = 0, Identify = 1, Identified = 2, Reidentify = 3, Event = 5, Request = 6, RequestResponse = 7, RequestBatch = 8, RequestBatchResponse = 9, }; enum WebSocketCloseCode { // Internal only DontClose = 0, // Reserved UnknownReason = 4000, // The requested `Content-Type` specified in the request HTTP header is invalid. InvalidContentType = 4001, // The server was unable to decode the incoming websocket message MessageDecodeError = 4002, // A data key is missing but required MissingDataKey = 4003, // A data key has an invalid type InvalidDataKeyType = 4004, // The specified `op` was invalid or missing UnknownOpCode = 4005, // The client sent a websocket message without first sending `Identify` message NotIdentified = 4006, // The client sent an `Identify` message while already identified AlreadyIdentified = 4007, // The authentication attempt (via `Identify`) failed AuthenticationFailed = 4008, // The server detected the usage of an old version of the obs-websocket RPC protocol. UnsupportedRpcVersion = 4009, // The websocket session has been invalidated by the obs-websocket server. SessionInvalidated = 4010, }; WebSocketServer(); ~WebSocketServer(); void Start(); void Stop(); void InvalidateSession(websocketpp::connection_hdl hdl); bool IsListening() { return _server.is_listening(); } std::vector GetWebSocketSessions(); QThreadPool *GetThreadPool() { return &_threadPool; } bool AuthenticationRequired; std::string AuthenticationSecret; std::string AuthenticationSalt; public Q_SLOTS: void BroadcastEvent(uint64_t requiredIntent, std::string eventType, json eventData = nullptr, uint8_t rpcVersion = 0); signals: void ClientConnected(const WebSocketSessionState state); void ClientDisconnected(const WebSocketSessionState state, const uint16_t closeCode); private: void ServerRunner(); void onOpen(websocketpp::connection_hdl hdl); void onClose(websocketpp::connection_hdl hdl); void onMessage(websocketpp::connection_hdl hdl, websocketpp::server::message_ptr message); std::thread _serverThread; websocketpp::server _server; QThreadPool _threadPool; std::mutex _sessionMutex; std::map> _sessions; uint16_t _serverPort; QString _serverPassword; bool _debugEnabled; };