#pragma once #include #include #include #include #include "utils/Utils.h" #include #include #include "WebSocketSession.h" class WebSocketServer : QObject { Q_OBJECT public: enum WebSocketCloseCode { // Internal only DontClose = 0, // Reserved UnknownReason = 4000, // The server was unable to decode the incoming websocket message MessageDecodeError = 4001, // The specified `messageType` was invalid or missing UnknownMessageType = 4002, // The client sent a websocket message without first sending `Identify` message NotIdentified = 4003, // The client sent an `Identify` message while already identified AlreadyIdentified = 4004, // The authentication attempt (via `Identify`) failed AuthenticationFailed = 4005, // There was an invalid parameter the client's `Identify` message InvalidIdentifyParameter = 4006, // A `Request` or `RequestBatch` was missing its `requestId` or `requestType` RequestMissingRequiredField = 4007, // The websocket session has been invalidated by the obs-websocket server. SessionInvalidated = 4008, // The server detected the usage of an old version of the obs-websocket protocol. UnsupportedProtocolVersion = 4009, // The requested `Content-Type` specified in the request HTTP header is invalid. InvalidContentType = 4010, }; enum WebSocketEncoding { Json, MsgPack }; struct WebSocketSessionState { websocketpp::connection_hdl hdl; std::string remoteAddress; uint64_t connectedAt; uint64_t incomingMessages; uint64_t outgoingMessages; bool isIdentified; }; 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 ClientIdentified(const WebSocketSessionState state); void ClientDisconnected(const WebSocketSessionState state, const uint16_t closeCode); void IdentifiedClientDisconnected(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; };