r5sdk/r5dev/rtech/liveapi/liveapi.cpp
Kawe Mazidjatari 54ef6a78e8 RTech: finalize decouple of websocket system + improvements
The WebSocket system is now fully split up. The global network module initialization is moved to DLL init so the websocket class could be used for anything. The LiveAPI system now also mostly runs in the server frame thread, the convar change callbacks still need to be latched to the server frame thread however.
2024-04-05 18:33:09 +02:00

172 lines
6.6 KiB
C++

//===========================================================================//
//
// Purpose: LiveAPI WebSocket implementation
//
//===========================================================================//
#include "liveapi.h"
#include "DirtySDK/dirtysock.h"
#include "DirtySDK/dirtysock/netconn.h"
#include "DirtySDK/proto/protossl.h"
#include "DirtySDK/proto/protowebsocket.h"
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
static void LiveAPI_ParamsChangedCallback(IConVar* var, const char* pOldValue)
{
// TODO[ AMOS ]: latch this off to the server frame thread!
LiveAPISystem()->UpdateParams();
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
static void LiveAPI_AddressChangedCallback(IConVar* var, const char* pOldValue)
{
// TODO[ AMOS ]: latch this off to the server frame thread!
LiveAPISystem()->InstallAddressList();
}
//-----------------------------------------------------------------------------
// console variables
//-----------------------------------------------------------------------------
ConVar liveapi_enabled("liveapi_enabled", "1", FCVAR_RELEASE | FCVAR_SERVER_FRAME_THREAD, "Enable LiveAPI functionality");
ConVar liveapi_session_name("liveapi_session_name", "liveapi_session", FCVAR_RELEASE | FCVAR_SERVER_FRAME_THREAD, "LiveAPI session name to identify this connection");
// WebSocket core
static ConVar liveapi_use_websocket("liveapi_use_websocket", "1", FCVAR_RELEASE | FCVAR_SERVER_FRAME_THREAD, "Use WebSocket to transmit LiveAPI events");
static ConVar liveapi_servers("liveapi_servers", "ws://127.0.0.1:7777", FCVAR_RELEASE | FCVAR_SERVER_FRAME_THREAD, "Comma separated list of addresses to connect to", &LiveAPI_AddressChangedCallback, "ws://domain.suffix:port");
// WebSocket connection base parameters
static ConVar liveapi_retry_count("liveapi_retry_count", "5", FCVAR_RELEASE | FCVAR_SERVER_FRAME_THREAD, "Amount of times to retry connecting before marking the connection as unavailable", &LiveAPI_ParamsChangedCallback);
static ConVar liveapi_retry_time("liveapi_retry_time", "30", FCVAR_RELEASE | FCVAR_SERVER_FRAME_THREAD, "Amount of time between each retry", &LiveAPI_ParamsChangedCallback);
// WebSocket connection context parameters
static ConVar liveapi_timeout("liveapi_timeout", "300", FCVAR_RELEASE | FCVAR_SERVER_FRAME_THREAD, "WebSocket connection timeout in seconds", &LiveAPI_ParamsChangedCallback);
static ConVar liveapi_keepalive("liveapi_keepalive", "30", FCVAR_RELEASE | FCVAR_SERVER_FRAME_THREAD, "Interval of time to send Pong to any connected server", &LiveAPI_ParamsChangedCallback);
static ConVar liveapi_lax_ssl("liveapi_lax_ssl", "1", FCVAR_RELEASE | FCVAR_SERVER_FRAME_THREAD, "Skip SSL certificate validation for all WSS connections (allows the use of self-signed certificates)", &LiveAPI_ParamsChangedCallback);
//-----------------------------------------------------------------------------
// constructors/destructors
//-----------------------------------------------------------------------------
LiveAPI::LiveAPI()
{
}
//-----------------------------------------------------------------------------
// Initialization of the LiveAPI system
//-----------------------------------------------------------------------------
void LiveAPI::Init()
{
if (!liveapi_enabled.GetBool())
return;
if (liveapi_use_websocket.GetBool())
{
const char* initError = nullptr;
if (!InitWebSocket(initError))
{
Error(eDLL_T::RTECH, 0, "LiveAPI: WebSocket initialization failed! [%s]\n", initError);
return;
}
}
}
//-----------------------------------------------------------------------------
// Shutdown of the LiveAPI system
//-----------------------------------------------------------------------------
void LiveAPI::Shutdown()
{
webSocketSystem.Shutdown();
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void LiveAPI::CreateParams(CWebSocket::ConnParams_s& params)
{
params.bufSize = LIVE_API_MAX_FRAME_BUFFER_SIZE;
params.retryTime = liveapi_retry_time.GetFloat();
params.maxRetries = liveapi_retry_count.GetInt();
params.timeOut = liveapi_timeout.GetInt();
params.keepAlive = liveapi_keepalive.GetInt();
params.laxSSL = liveapi_lax_ssl.GetInt();
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void LiveAPI::UpdateParams()
{
CWebSocket::ConnParams_s connParams;
CreateParams(connParams);
webSocketSystem.UpdateParams(connParams);
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
bool LiveAPI::InitWebSocket(const char*& initError)
{
CWebSocket::ConnParams_s connParams;
CreateParams(connParams);
return webSocketSystem.Init(liveapi_servers.GetString(), connParams, initError);
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void LiveAPI::InstallAddressList()
{
webSocketSystem.ClearAll();
webSocketSystem.UpdateAddressList(liveapi_servers.GetString());
}
//-----------------------------------------------------------------------------
// LiveAPI state machine
//-----------------------------------------------------------------------------
void LiveAPI::RunFrame()
{
if (!IsEnabled())
return;
if (liveapi_use_websocket.GetBool())
webSocketSystem.Update();
}
//-----------------------------------------------------------------------------
// Send an event to all sockets
//-----------------------------------------------------------------------------
void LiveAPI::LogEvent(const char* const dataBuf, const int32_t dataSize)
{
if (!IsEnabled())
return;
if (liveapi_use_websocket.GetBool())
webSocketSystem.SendData(dataBuf, dataSize);
}
//-----------------------------------------------------------------------------
// Returns whether the system is enabled and able to run
//-----------------------------------------------------------------------------
bool LiveAPI::IsEnabled() const
{
return liveapi_enabled.GetBool();
}
static LiveAPI s_liveApi;
//-----------------------------------------------------------------------------
// Singleton accessor
//-----------------------------------------------------------------------------
LiveAPI* LiveAPISystem()
{
return &s_liveApi;
}