Files
obs-websocket/src/WebSocketServer.h
tt2468 03e32c8b5e Base: Major protocol refactor
As discussed in the #development channel in discord
- Switch from using message types to integer op codes
- Consolidate op-specific keys into `d` sub-object
- Shorten low-level payload keys from `messageType` to `op`, add `d`

Other changes:
- The WebSocketCloseCode enum has been refactored. It's best to just
treat it like it's new
- Some performance benefits came along the way. Nothing gamechanging,
but notable
- Various bug fixes discovered while refactoring
2021-08-28 05:02:24 -07:00

115 lines
3.0 KiB
C++

#pragma once
#include <mutex>
#include <QObject>
#include <QThreadPool>
#include <QString>
#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/server.hpp>
#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<WebSocketSessionState> 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<websocketpp::config::asio>::message_ptr message);
std::thread _serverThread;
websocketpp::server<websocketpp::config::asio> _server;
QThreadPool _threadPool;
std::mutex _sessionMutex;
std::map<websocketpp::connection_hdl, SessionPtr, std::owner_less<websocketpp::connection_hdl>> _sessions;
uint16_t _serverPort;
QString _serverPassword;
bool _debugEnabled;
};