mirror of
https://github.com/Sani7/remote-ui.git
synced 2026-10-26 21:51:13 +01:00
- fix ssl errors when using reverse proxy in a regular application - switch over to reverse proxy by default - allow for debug host + port without ssl
226 lines
6.6 KiB
C++
226 lines
6.6 KiB
C++
#include "web_socket_wrapper.hpp"
|
|
#include <QTimer>
|
|
#include <QtWebSockets/QWebSocket>
|
|
#include <magic_enum/magic_enum.hpp>
|
|
|
|
#define LOG_SRC_LOC(level, msg) emit log_signal(__FILE__, __LINE__, __FUNCTION__, (int)(level), (msg))
|
|
#define LOG_TRACE(msg) LOG_SRC_LOC(Log_level_enum::trace, msg)
|
|
#define LOG_DEBUG(msg) LOG_SRC_LOC(Log_level_enum::debug, msg)
|
|
#define LOG_INFO(msg) LOG_SRC_LOC(Log_level_enum::info, msg)
|
|
#define LOG_WARN(msg) LOG_SRC_LOC(Log_level_enum::warn, msg)
|
|
#define LOG_ERROR(msg) LOG_SRC_LOC(Log_level_enum::err, msg)
|
|
#define LOG_CRITICAL(msg) LOG_SRC_LOC(Log_level_enum::critical, msg)
|
|
|
|
Web_socket_wrapper::Web_socket_wrapper(const QUrl &url, QObject *parent)
|
|
: QObject(parent), m_web_socket(new QWebSocket("", QWebSocketProtocol::VersionLatest, this)),
|
|
m_ping_timer(new QTimer(this)), m_pong_timer(new QTimer(this))
|
|
{
|
|
connect(m_web_socket, &QWebSocket::connected, this, [=, this] {
|
|
m_connected = true;
|
|
connect(m_web_socket, &QWebSocket::textMessageReceived, this, &Web_socket_wrapper::m_on_received);
|
|
m_ping_timer->start(5000);
|
|
emit on_connected();
|
|
});
|
|
connect(m_web_socket, &QWebSocket::disconnected, this, [=, this] { emit on_closed(); });
|
|
connect(m_web_socket, &QWebSocket::errorOccurred, this, [this](QAbstractSocket::SocketError error) {
|
|
LOG_ERROR(QString::fromStdString(std::string(magic_enum::enum_name(error))));
|
|
});
|
|
|
|
connect(m_ping_timer, &QTimer::timeout, this, [=, this] {
|
|
#ifdef EMSCRIPTEN
|
|
if (m_web_socket->state() != QAbstractSocket::ConnectedState)
|
|
{
|
|
m_web_socket->close();
|
|
emit on_closed();
|
|
}
|
|
m_ping_timer->start(1000);
|
|
});
|
|
#else
|
|
m_web_socket->ping();
|
|
m_pong_timer->start(1000);
|
|
});
|
|
connect(m_web_socket, &QWebSocket::pong, this, [=, this](quint64 elapsedTime) {
|
|
if (elapsedTime > 1000)
|
|
{
|
|
m_web_socket->close();
|
|
emit on_closed();
|
|
}
|
|
|
|
m_pong_timer->stop();
|
|
m_ping_timer->start(1000);
|
|
});
|
|
connect(m_pong_timer, &QTimer::timeout, this, [=, this] {
|
|
LOG_CRITICAL("Pong timeout");
|
|
m_web_socket->close();
|
|
emit on_closed();
|
|
});
|
|
connect(m_web_socket, &QWebSocket::sslErrors,
|
|
this, [&](const QList<QSslError> &errors) {
|
|
QList<QSslError> exeptions;
|
|
for (const auto &err : errors) {
|
|
if (err.error() == QSslError::UnableToGetLocalIssuerCertificate)
|
|
{
|
|
exeptions.append(err);
|
|
LOG_WARN(QString("Allowing ssl error: %1 from %2").arg("UnableToGetLocalIssuerCertificate").arg(!err.certificate().isNull() ? err.certificate().subjectDisplayName() : "Unknown"));
|
|
}
|
|
}
|
|
m_web_socket->ignoreSslErrors(exeptions);
|
|
});
|
|
#endif
|
|
m_ping_timer->setSingleShot(true);
|
|
m_pong_timer->setSingleShot(true);
|
|
m_web_socket->setProxy(QNetworkProxy::NoProxy);
|
|
m_web_socket->open(url);
|
|
}
|
|
|
|
void Web_socket_wrapper::send_command(Command c, size_t id)
|
|
{
|
|
json j;
|
|
j["command"]["type"] = magic_enum::enum_name(c).data();
|
|
switch (c)
|
|
{
|
|
case Command::get_UI_element:
|
|
j["command"]["id"] = id;
|
|
m_web_socket->sendTextMessage(QString(j.dump().data()));
|
|
break;
|
|
case Command::get_UI_elements:
|
|
m_web_socket->sendTextMessage(QString(j.dump().data()));
|
|
break;
|
|
case Command::get_active_simulator_name:
|
|
m_web_socket->sendTextMessage(QString(j.dump().data()));
|
|
break;
|
|
case Command::get_simulators:
|
|
m_web_socket->sendTextMessage(QString(j.dump().data()));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void Web_socket_wrapper::send_command(Command command, QString val)
|
|
{
|
|
json j;
|
|
j["command"]["type"] = magic_enum::enum_name(command).data();
|
|
switch (command)
|
|
{
|
|
case Command::switch_simulator:
|
|
j["command"]["name"] = val.toStdString();
|
|
m_web_socket->sendTextMessage(QString(j.dump().data()));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void Web_socket_wrapper::send_event(Event e, size_t id)
|
|
{
|
|
if (m_inhibit_events)
|
|
return;
|
|
json j;
|
|
j["event"]["type"] = magic_enum::enum_name(e).data();
|
|
switch (e)
|
|
{
|
|
case Event::clicked:
|
|
case Event::clear:
|
|
j["event"]["id"] = id;
|
|
m_web_socket->sendTextMessage(QString(j.dump().data()));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void Web_socket_wrapper::send_event(Event e, size_t id, size_t val)
|
|
{
|
|
if (m_inhibit_events)
|
|
return;
|
|
json j;
|
|
j["event"]["type"] = magic_enum::enum_name(e).data();
|
|
switch (e)
|
|
{
|
|
case Event::selected:
|
|
j["event"]["id"] = id;
|
|
j["event"]["selected"] = val;
|
|
m_web_socket->sendTextMessage(QString(j.dump().data()));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void Web_socket_wrapper::send_event(Event e, size_t id, double val)
|
|
{
|
|
if (m_inhibit_events)
|
|
return;
|
|
json j;
|
|
j["event"]["type"] = magic_enum::enum_name(e).data();
|
|
switch (e)
|
|
{
|
|
case Event::value_changed:
|
|
j["event"]["id"] = id;
|
|
j["event"]["value"] = val;
|
|
m_web_socket->sendTextMessage(QString(j.dump().data()));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void Web_socket_wrapper::send_event(Event e, size_t id, QString val)
|
|
{
|
|
if (m_inhibit_events)
|
|
return;
|
|
json j;
|
|
j["event"]["type"] = magic_enum::enum_name(e).data();
|
|
switch (e)
|
|
{
|
|
case Event::text_changed:
|
|
j["event"]["id"] = id;
|
|
j["event"]["text"] = val.toStdString();
|
|
m_web_socket->sendTextMessage(QString(j.dump().data()));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void Web_socket_wrapper::send_event(Event e, size_t id, uint32_t sid, uint8_t dlc, std::array<uint8_t, 8> payload)
|
|
{
|
|
if (m_inhibit_events)
|
|
return;
|
|
json j;
|
|
j["event"]["type"] = magic_enum::enum_name(e).data();
|
|
switch (e)
|
|
{
|
|
case Event::can_send:
|
|
j["event"]["id"] = id;
|
|
j["event"]["sid"] = sid;
|
|
j["event"]["dlc"] = dlc;
|
|
j["event"]["payload"] = payload;
|
|
m_web_socket->sendTextMessage(QString(j.dump().data()));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void Web_socket_wrapper::m_on_received(QString message)
|
|
{
|
|
json j = json::parse(message.toStdString());
|
|
if (j.contains("response"))
|
|
{
|
|
emit on_command_cb(j.at("response"));
|
|
return;
|
|
}
|
|
if (j.contains("event"))
|
|
{
|
|
emit on_event_cb(j.at("event"));
|
|
return;
|
|
}
|
|
}
|
|
|
|
void Web_socket_wrapper::inhibit_events(bool inhibit)
|
|
{
|
|
m_inhibit_events = inhibit;
|
|
}
|