2021-04-27 16:18:06 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <QObject>
|
2021-04-27 21:52:48 +00:00
|
|
|
#include <QThreadPool>
|
2021-04-28 17:27:32 +00:00
|
|
|
#include <mutex>
|
2021-04-27 21:52:48 +00:00
|
|
|
|
2021-04-27 16:46:00 +00:00
|
|
|
#include <nlohmann/json.hpp>
|
2021-04-27 21:52:48 +00:00
|
|
|
#include <websocketpp/config/asio_no_tls.hpp>
|
|
|
|
#include <websocketpp/server.hpp>
|
2021-04-27 16:18:06 +00:00
|
|
|
|
2021-04-27 21:52:48 +00:00
|
|
|
#include "WebSocketSession.h"
|
2021-04-27 16:29:51 +00:00
|
|
|
|
2021-04-27 21:52:48 +00:00
|
|
|
using json = nlohmann::json;
|
|
|
|
|
2021-04-28 17:27:32 +00:00
|
|
|
class WebSocketServer
|
2021-04-27 16:18:06 +00:00
|
|
|
{
|
|
|
|
public:
|
2021-04-27 22:29:09 +00:00
|
|
|
enum WebsocketCloseCode: std::uint16_t {
|
|
|
|
UnknownReason = 4000,
|
|
|
|
// The server was unable to decode the incoming websocket message
|
|
|
|
MessageDecodeError = 4001,
|
|
|
|
// The specified `messageType` was invalid
|
|
|
|
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`
|
|
|
|
RequestMissingRequestId = 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,
|
|
|
|
};
|
|
|
|
|
|
|
|
struct WebSocketState {
|
|
|
|
websocketpp::connection_hdl hdl;
|
|
|
|
std::string remoteAddress;
|
|
|
|
uint64_t durationSeconds;
|
|
|
|
uint64_t incomingMessages;
|
|
|
|
uint64_t outgoingMessages;
|
|
|
|
};
|
|
|
|
|
2021-04-27 21:52:48 +00:00
|
|
|
WebSocketServer();
|
|
|
|
~WebSocketServer();
|
|
|
|
|
|
|
|
void Start();
|
|
|
|
void Stop();
|
|
|
|
void InvalidateSession(websocketpp::connection_hdl hdl);
|
|
|
|
|
2021-04-27 22:25:11 +00:00
|
|
|
bool IsListening() {
|
|
|
|
return _server.is_listening();
|
|
|
|
}
|
|
|
|
|
2021-04-27 21:52:48 +00:00
|
|
|
std::vector<WebSocketState> GetWebSocketSessions();
|
|
|
|
|
|
|
|
QThreadPool *GetThreadPool() {
|
|
|
|
return &_threadPool;
|
|
|
|
}
|
|
|
|
|
2021-04-27 23:33:47 +00:00
|
|
|
std::string GetConnectUrl();
|
|
|
|
|
2021-04-27 21:52:48 +00:00
|
|
|
void BroadcastEvent(uint64_t requiredIntent, std::string eventType, json eventData = nullptr);
|
2021-04-27 16:46:00 +00:00
|
|
|
|
|
|
|
private:
|
2021-04-28 17:27:32 +00:00
|
|
|
void ServerRunner();
|
2021-04-27 23:33:47 +00:00
|
|
|
WebSocketSession *GetWebSocketSession(websocketpp::connection_hdl hdl);
|
|
|
|
|
2021-04-27 21:52:48 +00:00
|
|
|
void onOpen(websocketpp::connection_hdl hdl);
|
|
|
|
void onClose(websocketpp::connection_hdl hdl);
|
2021-04-27 23:33:47 +00:00
|
|
|
void onMessage(websocketpp::connection_hdl hdl, websocketpp::server<websocketpp::config::asio>::message_ptr message);
|
2021-04-27 21:52:48 +00:00
|
|
|
|
2021-04-28 17:27:32 +00:00
|
|
|
std::thread _serverThread;
|
2021-04-27 21:52:48 +00:00
|
|
|
websocketpp::server<websocketpp::config::asio> _server;
|
|
|
|
QThreadPool _threadPool;
|
2021-04-28 17:27:32 +00:00
|
|
|
std::mutex _sessionMutex;
|
2021-04-27 21:52:48 +00:00
|
|
|
std::map<websocketpp::connection_hdl, WebSocketSession, std::owner_less<websocketpp::connection_hdl>> _sessions;
|
2021-04-27 23:33:47 +00:00
|
|
|
uint16_t _serverPort;
|
2021-04-28 17:27:32 +00:00
|
|
|
std::string _authenticationSecret;
|
|
|
|
std::string _authenticationSalt;
|
2021-04-27 21:52:48 +00:00
|
|
|
};
|