update websocket
updated to use protobuf
not quite finished with the Websocket message parser
This commit is contained in:
2026-08-20 13:27:32 +02:00
parent cb41ac2aa2
commit 338bd461af
9 changed files with 220 additions and 220 deletions
+1
View File
@@ -57,6 +57,7 @@ target_sources(server_common
target_link_libraries(server_common
PUBLIC
UI
proto-ui
spdlog
cpp_templates
${GPIOD_LIB}
+90 -95
View File
@@ -3,122 +3,122 @@
#include <magic_enum/magic_enum.hpp>
#include <spdlog/spdlog.h>
QString Simulators::message_parser(QString message)
// TODO: Fix parsing messages
QByteArray Simulators::message_parser(QByteArray message)
{
json j = json::parse(message.toStdString());
if (j.contains("command"))
Event_m event_m;
bool event = m_serializer.deserialize(&event_m, message);
// if (j.contains("command"))
// {
// return QString::fromStdString(command_parser(j["command"]).dump());
// }
/*else*/ if (event)
{
return QString::fromStdString(command_parser(j["command"]).dump());
event_handler(event_m);
}
else if (j.contains("event"))
{
event_handler(j["event"]);
}
return "{}";
return QByteArray();
}
json Simulators::command_parser(json command)
{
json j = "{}"_json;
try
{
std::string type = command.at("type");
Command cmd = magic_enum::enum_cast<Command>(type).value_or(Command::end);
switch (cmd)
{
case Command::get_UI_element:
SPDLOG_INFO("Command {}: {}", type, (size_t)command.at("id"));
if (is_not_active())
{
SPDLOG_ERROR("Command got called but there is no active simulator");
return j;
}
j["response"]["type"] = type;
j["response"]["UI_item"] =
invoke_active_simulator()->get_UI_item(command.at("id"))->to_json(command.at("id"));
break;
case Command::get_UI_elements:
SPDLOG_INFO("Command {}", type);
if (is_not_active())
{
SPDLOG_ERROR("Command got called but there is no active simulator");
return j;
}
j["response"]["type"] = type;
j["response"]["UI_items"] = invoke_active_simulator()->get_UI_items()["UI_items"];
break;
case Command::switch_simulator:
SPDLOG_INFO("Command {} to {}", type, std::string(command.at("name")));
switch_simulator(command.at("name"));
j["response"]["type"] = type;
break;
case Command::get_active_simulator_name:
SPDLOG_INFO("Command {}", type);
j["response"]["type"] = type;
j["response"]["name"] = active_simulator_name();
break;
case Command::get_simulators:
SPDLOG_INFO("Command {}", type);
j["response"]["type"] = type;
j["response"]["simulators"] = list_simulators();
break;
default:
break;
}
}
catch (const json::exception &e)
{
SPDLOG_ERROR("{} {}", __FUNCTION__, e.what());
}
// QByteArray Simulators::command_parser(json command)
// {
// json j = "{}"_json;
// try
// {
// std::string type = command.at("type");
// Command cmd = magic_enum::enum_cast<Command>(type).value_or(Command::end);
// switch (cmd)
// {
// case Command::get_UI_element:
// SPDLOG_INFO("Command {}: {}", type, (size_t)command.at("id"));
// if (is_not_active())
// {
// SPDLOG_ERROR("Command got called but there is no active simulator");
// return j;
// }
// j["response"]["type"] = type;
// j["response"]["UI_item"] =
// invoke_active_simulator()->get_UI_item(command.at("id"))->to_json(command.at("id"));
// break;
// case Command::get_UI_elements:
// SPDLOG_INFO("Command {}", type);
// if (is_not_active())
// {
// SPDLOG_ERROR("Command got called but there is no active simulator");
// return j;
// }
// j["response"]["type"] = type;
// j["response"]["UI_items"] = invoke_active_simulator()->get_UI_items()["UI_items"];
// break;
// case Command::switch_simulator:
// SPDLOG_INFO("Command {} to {}", type, std::string(command.at("name")));
// switch_simulator(command.at("name"));
// j["response"]["type"] = type;
// break;
// case Command::get_active_simulator_name:
// SPDLOG_INFO("Command {}", type);
// j["response"]["type"] = type;
// j["response"]["name"] = active_simulator_name();
// break;
// case Command::get_simulators:
// SPDLOG_INFO("Command {}", type);
// j["response"]["type"] = type;
// j["response"]["simulators"] = list_simulators();
// break;
// default:
// break;
// }
// }
// catch (const json::exception &e)
// {
// SPDLOG_ERROR("{} {}", __FUNCTION__, e.what());
// }
return j;
}
// return j;
// }
void Simulators::event_handler(json event)
void Simulators::event_handler(Event_m event)
{
try
{
std::string type = event.at("type");
Event e = magic_enum::enum_cast<Event>(type).value_or(Event::end);
if (invoke_active_simulator() == nullptr)
{
SPDLOG_ERROR("Event got called but there is no active simulator");
return;
}
switch (e)
QString type; // = QString::fromStdString(magic_enum::enum_cast<Event_m::KindFields>(event.kindField()).value_or(Event_m::KindFields::UninitializedField));
switch (event.kindField())
{
case Event::clicked: {
SPDLOG_DEBUG("Event {}: {}", type, (size_t)event.at("id"));
invoke_active_simulator()->get_UI_item(event.at("id"))->click();
case Event_m::KindFields::Clicked: {
SPDLOG_DEBUG("Event {}: {}", type, (size_t)event.id_proto());
invoke_active_simulator()->get_UI_item(event.id_proto())->click();
break;
}
case Event::value_changed: {
SPDLOG_DEBUG("Event {}: {} {}", type, (size_t)event.at("id"), (double)(event["value"]));
invoke_active_simulator()->get_UI_item(event.at("id"))->set_value((double)event.at("value"));
case Event_m::KindFields::ValueChanged: {
SPDLOG_DEBUG("Event {}: {} {}", type, event.id_proto(), event.valueChanged().value());
invoke_active_simulator()->get_UI_item(event.id_proto())->set_value(event.valueChanged().value());
break;
}
case Event::text_changed: {
SPDLOG_DEBUG("Event {}: {} {}", type, (size_t)event.at("id"), std::string(event.at("text")));
invoke_active_simulator()->get_UI_item(event.at("id"))->set_text(std::string(event.at("text")));
case Event_m::KindFields::TextChanged: {
SPDLOG_DEBUG("Event {}: {} {}", type, event.id_proto(), event.textChanged().text());
invoke_active_simulator()->get_UI_item(event.id_proto())->set_text(event.textChanged().text());
break;
}
case Event::selected: {
SPDLOG_DEBUG("Event {}: {} {}", type, (size_t)event.at("id"), std::to_string((size_t)event.at("selected")));
invoke_active_simulator()->get_UI_item(event.at("id"))->set_selected(event.at("selected"));
case Event_m::KindFields::Selected: {
SPDLOG_DEBUG("Event {}: {} {}", type, event.id_proto(), std::to_string(event.selected().selected()));
invoke_active_simulator()->get_UI_item(event.id_proto())->set_selected(event.selected().selected());
break;
}
case Event::can_send: {
SPDLOG_DEBUG("Event {}: {}", type, (size_t)event.at("id"));
case Event_m::KindFields::CanSend: {
SPDLOG_DEBUG("Event {}: {}", type, event.id_proto());
invoke_active_simulator()
->get_UI_item(event.at("id"))
->can_send((uint32_t)event.at("sid"), (uint8_t)event.at("dlc"),
(std::array<uint8_t, 8>)event.at("payload"));
->get_UI_item(event.id_proto())
->can_send(event.canSend().frame().sid(), event.canSend().frame().dlc(),
event.canSend().frame().payload());
break;
}
case Event::clear: {
SPDLOG_DEBUG("Event {}: {}", type, (size_t)event.at("id"));
invoke_active_simulator()->get_UI_item(event.at("id"))->clear();
case Event_m::KindFields::Clear: {
SPDLOG_DEBUG("Event {}: {}", type, event.id_proto());
invoke_active_simulator()->get_UI_item(event.id_proto())->clear();
break;
}
default: {
@@ -126,8 +126,3 @@ void Simulators::event_handler(json event)
}
}
}
catch (const json::exception &e)
{
SPDLOG_ERROR("{} {}", __FUNCTION__, e.what());
}
}
+6 -6
View File
@@ -2,7 +2,7 @@
#include "simulator_base.hpp"
#include "ui_item.hpp"
Simulator_base::Simulator_base(std::string name, Communication *com, std::chrono::milliseconds interval,
Simulator_base::Simulator_base(QString name, Communication *com, std::chrono::milliseconds interval,
QObject *parent)
: QObject(parent), m_name(name), m_timer(new QTimer(this)), m_interval(interval), m_com(com)
{
@@ -10,7 +10,7 @@ Simulator_base::Simulator_base(std::string name, Communication *com, std::chrono
m_UI_items.reserve(50);
}
std::string Simulator_base::name() const
QString Simulator_base::name() const
{
// Get the name of the simulator
return m_name;
@@ -20,17 +20,17 @@ void Simulator_base::push_ui_item(UI_item *item)
{
// Add a UI item to the simulator
connect(item, &UI_item::ui_changed, this, [this] { emit sim_changed(); });
item->set_id(m_UI_items.size());
m_UI_items.push_back(item);
}
json Simulator_base::get_UI_items() const
QList<UI_item_m> Simulator_base::get_UI_items() const
{
// Get the UI items
json items;
items["name"] = m_name;
QList<UI_item_m> items;
for (size_t i = 0; i < m_UI_items.size(); i++)
{
items["UI_items"].push_back(m_UI_items[i]->to_json(i));
items.push_back(m_UI_items[i]->to_proto());
}
return items;
+10 -22
View File
@@ -7,11 +7,8 @@
#ifndef INTERNAL
#include "ui.hpp"
#else
#include <nlohmann/json.hpp>
using json = nlohmann::json;
Q_FORWARD_DECLARE_OBJC_CLASS(UI_item);
Q_FORWARD_DECLARE_OBJC_CLASS(UI_item_m);
#endif
#define PUSH_UI_ITEM(item) push_ui_item(&item)
@@ -75,15 +72,15 @@ class Simulator_base : public QObject
* @param interval The interval of the timer (default is 100ms)
* @param parent The parent QObject
*/
Simulator_base(std::string name, Communication *comms,
Simulator_base(QString name, Communication *comms,
std::chrono::milliseconds interval = std::chrono::milliseconds(100), QObject *parent = nullptr);
/**
* @brief Returns the name of the simulator
*
* @return std::string The name of the simulator
* @return QString The name of the simulator
*/
std::string name() const;
QString name() const;
/**
* @brief This function adds a UI item to the simulator
@@ -98,7 +95,7 @@ class Simulator_base : public QObject
*
* @return json The UI items in json format
*/
json get_UI_items() const;
QList<UI_item_m> get_UI_items() const;
/**
* @brief Get the UI item object by id
@@ -112,20 +109,11 @@ class Simulator_base : public QObject
* @brief Get the id of a UI item by pointer
*
* @param ptr A pointer to the UI item
* @return size_t The id of the UI item, or -1 if not found
* @return qsizetype The id of the UI item, or -1 if not found
*/
size_t ptr_to_id(UI_item *ptr) const
qsizetype ptr_to_id(UI_item *ptr) const
{
size_t id = 0;
while (id < m_UI_items.size())
{
if (m_UI_items[id] == ptr)
{
return id;
}
id++;
}
return (size_t)-1;
return m_UI_items.indexOf(ptr);
}
/**
@@ -196,12 +184,12 @@ class Simulator_base : public QObject
* @brief The name of the simulator
*
*/
std::string m_name;
QString m_name;
/**
* @brief The UI items of the simulator
*
*/
std::vector<UI_item *> m_UI_items;
QList<UI_item *> m_UI_items;
/**
* @brief The timer for the simulator
*
+41 -50
View File
@@ -7,7 +7,6 @@
#include <QDirIterator>
#include <QLibrary>
#include <QThread>
#include <unordered_set>
typedef Simulator_base *(*Get_Sim)(Communication *, QObject *);
@@ -71,17 +70,17 @@ Simulators::Simulators(uint16_t port, QStringList can_devs, QStringList uart_dev
lib.unload();
continue;
}
m_simulators.insert(std::make_pair(widget->name(), widget));
m_simulators.insert(widget->name(), widget);
}
// Insert Debug sims here
// INSERT_SIMULATOR(TEST_SIM);
connect(m_server, &Websocket::on_message, this, [this](QWebSocket *conn, QString message) {
QString response = message_parser(message);
if (response == "{}")
connect(m_server, &Websocket::on_binary_message, this, [this](QWebSocket *conn, QByteArray message) {
QByteArray response = message_parser(message);
if (response.isEmpty())
return;
m_server->send(conn, response);
m_server->send_binary(conn, response);
});
}
@@ -89,7 +88,7 @@ Simulators::~Simulators()
{
}
std::string Simulators::active_simulator_name() const
QString Simulators::active_simulator_name() const
{
return this->m_current_simulator;
}
@@ -101,14 +100,14 @@ void Simulators::start()
SPDLOG_WARN("No simulators found");
return;
}
if (this->m_current_simulator.empty())
if (this->m_current_simulator.isEmpty())
{
SPDLOG_WARN("No active simulator");
return;
}
m_before = this->m_simulators.at(m_current_simulator)->get_UI_items();
this->m_simulators.at(m_current_simulator)->start();
m_before = this->m_simulators.value(m_current_simulator)->get_UI_items();
this->m_simulators.value(m_current_simulator)->start();
}
void Simulators::stop()
@@ -118,16 +117,16 @@ void Simulators::stop()
SPDLOG_WARN("No simulators found");
return;
}
if (this->m_current_simulator.empty())
if (this->m_current_simulator.isEmpty())
{
SPDLOG_WARN("No active simulator");
return;
}
this->m_simulators.at(m_current_simulator)->stop();
this->m_simulators.value(m_current_simulator)->stop();
}
void Simulators::switch_simulator(std::string name)
void Simulators::switch_simulator(QString name)
{
if (this->m_simulators.empty())
{
@@ -136,29 +135,31 @@ void Simulators::switch_simulator(std::string name)
}
if (this->m_simulators.find(name) == this->m_simulators.end())
{
SPDLOG_WARN("Simulator {} not found", name);
SPDLOG_WARN("Simulator {} not found", name.toStdString());
return;
}
if (!this->m_current_simulator.empty())
if (!this->m_current_simulator.isEmpty())
{
SPDLOG_INFO("Stopping current simulator {} and switching to {}", m_current_simulator, name);
this->m_simulators.at(m_current_simulator)->stop();
disconnect(m_simulators.at(m_current_simulator).get());
SPDLOG_INFO("Stopping current simulator {} and switching to {}", m_current_simulator.toStdString(), name.toStdString());
this->m_simulators.value(m_current_simulator)->stop();
disconnect(m_simulators.value(m_current_simulator));
}
this->m_current_simulator = name;
connect(
m_simulators.at(m_current_simulator).get(), &Simulator_base::sim_changed, this,
m_simulators.value(m_current_simulator), &Simulator_base::sim_changed, this,
[this] {
auto json = changed_UI_items();
if (!json.empty())
auto changed = changed_UI_items();
UI_items_m items;
items.setItem(changed);
if (!changed.isEmpty())
{
m_server->broadcast(QString::fromStdString(json.dump()));
m_server->broadcast_binary(m_serializer.serialize(&items));
}
},
Qt::QueuedConnection);
connect(m_simulators.at(m_current_simulator).get(), &Simulator_base::log_signal, this,
connect(m_simulators.value(m_current_simulator), &Simulator_base::log_signal, this,
[](const char *filename_in, int line_in, const char *funcname_in, int level, QString msg) {
if (spdlog::default_logger_raw()->should_log((spdlog::level::level_enum)level))
spdlog::default_logger_raw()->log(spdlog::source_loc{filename_in, line_in, funcname_in},
@@ -167,19 +168,14 @@ void Simulators::switch_simulator(std::string name)
this->start();
}
std::vector<std::string> Simulators::list_simulators() const
QList<QString> Simulators::list_simulators() const
{
std::vector<std::string> names;
for (const auto &simulator : this->m_simulators)
{
names.push_back(simulator.first);
}
return names;
return this->m_simulators.keys();
}
bool Simulators::is_not_active() const
{
return this->m_current_simulator.empty();
return this->m_current_simulator.isEmpty();
}
Simulator_base *Simulators::invoke_active_simulator()
@@ -189,45 +185,40 @@ Simulator_base *Simulators::invoke_active_simulator()
{
return nullptr;
}
if (this->m_current_simulator.empty())
if (this->m_current_simulator.isEmpty())
{
return nullptr;
}
m_before = this->m_simulators.at(m_current_simulator)->get_UI_items();
m_before = this->m_simulators.value(m_current_simulator)->get_UI_items();
return this->m_simulators.at(m_current_simulator).get();
return this->m_simulators.value(m_current_simulator);
}
json Simulators::changed_UI_items()
QList<UI_item_m> Simulators::changed_UI_items()
{
std::lock_guard<std::mutex> lock(m_mutex);
QList<UI_item_m> ret;
if (this->m_simulators.empty() || this->m_current_simulator.empty())
return "{}"_json;
if (this->m_simulators.empty() || this->m_current_simulator.isEmpty())
return ret;
json after = this->m_simulators.at(m_current_simulator)->get_UI_items();
auto after = this->m_simulators.value(m_current_simulator)->get_UI_items();
// Fast path: nothing at all changed
if (after == m_before)
return "{}"_json;
return ret;
json changed;
changed["event"]["type"] = "ui_changed";
const auto &ui_items = after["UI_items"];
const auto &prev_ui_items = m_before["UI_items"]; // may be null on first call
const size_t count = ui_items.size();
for (size_t i = 0; i < count; ++i)
const qsizetype count = after.size();
for (qsizetype i = 0; i < count; ++i)
{
// If item is new or any field changed -> send full current item
if (i >= prev_ui_items.size() || ui_items[i] != prev_ui_items[i])
if (i >= m_before.size() || after[i] != m_before[i])
{
changed["event"]["UI_items"].push_back(ui_items[i]);
ret.push_back(after[i]);
}
}
m_before = std::move(after);
return changed;
return ret;
}
+17 -16
View File
@@ -1,9 +1,10 @@
#pragma once
#include <QObject>
#include <map>
#include <QMap>
#include <memory>
#include <mutex>
#include <nlohmann/json.hpp>
#include <QProtobufSerializer>
#include <messages.qpb.h>
#define INSERT_SIMULATOR(type) \
m_simulators.insert(std::make_pair(type(&m_com).name(), std::make_unique<type>(&m_com, this)));
@@ -14,8 +15,7 @@ Q_FORWARD_DECLARE_OBJC_CLASS(CAN_Wrapper);
Q_FORWARD_DECLARE_OBJC_CLASS(QSerialPort);
Q_FORWARD_DECLARE_OBJC_CLASS(Simulator_base);
Q_FORWARD_DECLARE_OBJC_CLASS(Communication);
using json = nlohmann::json;
Q_FORWARD_DECLARE_OBJC_CLASS(UI_item_m);
/**
* @brief Class managing all simulators
@@ -75,9 +75,9 @@ class Simulators : public QObject
/**
* @brief Get the name of the active simulator
*
* @return std::string The name of the active simulator
* @return QString The name of the active simulator
*/
std::string active_simulator_name() const;
QString active_simulator_name() const;
/**
* @brief Start the active simulator
*
@@ -93,13 +93,13 @@ class Simulators : public QObject
*
* @param name The name of the simulator to switch to
*/
void switch_simulator(std::string name);
void switch_simulator(QString name);
/**
* @brief List all available simulators
*
* @return std::vector<std::string> A list of simulator names
* @return std::vector<QString> A list of simulator names
*/
std::vector<std::string> list_simulators() const;
QList<QString> list_simulators() const;
/**
* @brief Check if no simulator is active
*
@@ -120,7 +120,7 @@ class Simulators : public QObject
*
* @return json The changed UI items
*/
json changed_UI_items();
QList<UI_item_m> changed_UI_items();
// Functions in message_parser.cpp
/**
@@ -129,27 +129,28 @@ class Simulators : public QObject
* @param message The message to parse
* @return QString The parsed message
*/
QString message_parser(QString message);
QByteArray message_parser(QByteArray message);
/**
* @brief Parse a command in json format
*
* @param command The command to parse
* @return json The parsed command
*/
json command_parser(json command);
//json command_parser(json command);
/**
* @brief Handle an event in json format
*
* @param event The event to handle
*/
void event_handler(json event);
void event_handler(Event_m event);
private:
QThread *m_server_thread;
Websocket *m_server;
Communication *m_com;
std::map<std::string, std::unique_ptr<Simulator_base>> m_simulators;
std::string m_current_simulator = "";
QMap<QString, Simulator_base*> m_simulators;
QString m_current_simulator = "";
std::mutex m_mutex;
json m_before;
QList<UI_item_m> m_before;
QProtobufSerializer m_serializer;
};
+6 -6
View File
@@ -5,10 +5,10 @@ EXPORT_SIM(Test_Sim);
Test_Sim::Test_Sim(Communication *com, QObject *parent)
: Simulator_base("Test Sim", com, std::chrono::milliseconds(1000), parent),
m_button("Off", Color::White, Color::Red),
m_combobox(Color::White, Color::Black, {"Option 1", "Option 2", "Option 3"}, 0),
m_combobox({"Option 1", "Option 2", "Option 3"}, 0),
m_label("Label", Color::White, Color::Black), m_checkbox("Option 1", Color::Default, Color::Default),
m_slider("Slider", Color::White, Color::Black, 0, 100, 0), m_dial("Dial", Color::White, Color::Black, 0, 100, 0),
m_thermo("Thermo", "%", Color::White, Color::Black, 0, 100, 0), m_led("Led", Color::White, Color::Red),
m_slider("Slider", 0, 100, 0), m_dial("Dial", 0, 100, 0),
m_thermo("Thermo", "%", 0, 100, 0), m_led("Led", Color::White, Color::Red),
m_table(4, 4, {"Row 1", "Row 2", "Row 3", "Row 4"}, {"Column 1", "Column 2", "Column 3", "Column 4"}),
m_spinbox(0, 255, 0), m_double_spinbox(0, 255, 0), m_hex_spinbox(0, 255, 0),
m_tab_widget({"Tab 1", "Tab 2", "Tab 3"}, 0), m_stacked_widget(3, 0), m_status_bar()
@@ -39,7 +39,7 @@ Test_Sim::Test_Sim(Communication *com, QObject *parent)
for (size_t i = 0; i < m_table.capacity(); i++)
{
m_table.insert_item(i / 4, i % 4, QString("%0 %1").arg(i / 4).arg(i % 4).toStdString());
m_table.insert_item(i / 4, i % 4, QString("%0 %1").arg(i / 4).arg(i % 4));
}
QObject::connect(&m_button, &UI_button::clicked, this, [=, this] { button_clicked(&m_button); });
@@ -87,14 +87,14 @@ void Test_Sim::slider_changed(UI_slider *id, double value)
if (id == &m_slider)
{
LOG_INFO(QString("Test slider changed to %0").arg(value));
m_label.set_text(std::to_string(value));
m_label.set_text(QString::number(value));
m_dial.set_value(value);
m_thermo.set_value(value);
m_plot.add_value(value);
m_spinbox.set_value(value);
m_double_spinbox.set_value(value);
m_hex_spinbox.set_value(value);
m_status_bar.show_message("Test slider changed to " + std::to_string(value));
m_status_bar.show_message("Test slider changed to " + QString::number(value));
return;
}
}
+23 -3
View File
@@ -60,7 +60,15 @@ Websocket::~Websocket()
qDeleteAll(m_clients.begin(), m_clients.end());
}
void Websocket::broadcast(QString message)
void Websocket::broadcast_binary(QByteArray message)
{
foreach (QWebSocket *conn, m_clients)
{
conn->sendBinaryMessage(message);
}
}
void Websocket::broadcast_text(QString message)
{
foreach (QWebSocket *conn, m_clients)
{
@@ -68,7 +76,12 @@ void Websocket::broadcast(QString message)
}
}
void Websocket::send(QWebSocket *conn, QString message)
void Websocket::send_binary(QWebSocket *conn, QByteArray message)
{
conn->sendBinaryMessage(message);
}
void Websocket::send_text(QWebSocket *conn, QString message)
{
conn->sendTextMessage(message);
}
@@ -77,16 +90,23 @@ void Websocket::onNewConnection()
{
QWebSocket *pSocket = m_pWebSocketServer->nextPendingConnection();
connect(pSocket, &QWebSocket::binaryMessageReceived, this, &Websocket::processBinaryMessage);
connect(pSocket, &QWebSocket::textMessageReceived, this, &Websocket::processTextMessage);
connect(pSocket, &QWebSocket::disconnected, this, &Websocket::socketDisconnected);
m_clients << pSocket;
}
void Websocket::processBinaryMessage(QByteArray message)
{
QWebSocket *pClient = qobject_cast<QWebSocket *>(sender());
emit on_binary_message(pClient, message);
}
void Websocket::processTextMessage(QString message)
{
QWebSocket *pClient = qobject_cast<QWebSocket *>(sender());
emit on_message(pClient, message);
emit on_text_message(pClient, message);
}
void Websocket::socketDisconnected()
+7 -3
View File
@@ -41,14 +41,16 @@ class Websocket : public QObject
*
* @param message The message to send
*/
void broadcast(QString message);
void broadcast_binary(QByteArray message);
void broadcast_text(QString message);
/**
* @brief Send a message to a specific client
*
* @param conn The client connection
* @param message The message to send
*/
void send(QWebSocket *conn, QString message);
void send_binary(QWebSocket *conn, QByteArray message);
void send_text(QWebSocket *conn, QString message);
signals:
/**
* @brief Signal emitted when a message is received from a client
@@ -56,7 +58,8 @@ class Websocket : public QObject
* @param conn The client connection
* @param message The received message
*/
void on_message(QWebSocket *conn, QString message);
void on_binary_message(QWebSocket *conn, QByteArray message);
void on_text_message(QWebSocket *conn, QString message);
/**
* @brief Signal emitted when the server is closed
*
@@ -74,6 +77,7 @@ class Websocket : public QObject
*
* @param message The received message
*/
void processBinaryMessage(QByteArray message);
void processTextMessage(QString message);
/**
* @brief Private Slot called when a client disconnects