Continues migration with DDS, Common
This commit is contained in:
1 parent
9b15cee841
commit
fa48db111e
668 files changed
+111841
-2
No files matched your search
Executable
+79
@@ -0,0 +1,79 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
# Created by Philipp Dassow, SLST, 2017-11-28
|
||||
|
||||
#
|
||||
# --- Library LtsWebSocketCommon --------------------------------------------------------------------------------
|
||||
#
|
||||
SET(LtsWebSocketCommon_SRCS
|
||||
client_message_factory.cpp
|
||||
client_message_factory.h
|
||||
client_message.cpp
|
||||
client_message.h
|
||||
reply_message.cpp
|
||||
reply_message.h
|
||||
data_manager_base_dl.h
|
||||
json_keys.h
|
||||
|
||||
logger.cpp
|
||||
logger.h
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY2(WS AAR SV LtsWebSocketCommon SHARED ${LtsWebSocketCommon_SRCS})
|
||||
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(LtsWebSocketCommon
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
||||
)
|
||||
|
||||
NGL_TARGET_LINK_LIBRARIES(LtsWebSocketCommon
|
||||
Qt5::Core
|
||||
Qt5::WebSockets
|
||||
NGLLogger
|
||||
)
|
||||
|
||||
#
|
||||
# --- Library ltsWebSocketServer --------------------------------------------------------------------------------
|
||||
#
|
||||
SET(LtsWebSocketServer_SRCS
|
||||
client_connection.cpp
|
||||
client_connection.h
|
||||
connection_handler.cpp
|
||||
connection_handler.h
|
||||
lts_web_socket_server.cpp
|
||||
lts_web_socket_server.h
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY2(WS AAR SV LtsWebSocketServer SHARED ${LtsWebSocketServer_SRCS})
|
||||
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(LtsWebSocketServer
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
||||
)
|
||||
|
||||
NGL_TARGET_LINK_LIBRARIES(LtsWebSocketServer
|
||||
Qt5::Core
|
||||
LtsWebSocketCommon
|
||||
)
|
||||
|
||||
#
|
||||
# --- Library ltsWebSocketClient --------------------------------------------------------------------------------
|
||||
#
|
||||
SET(LtsWebSocketClient_SRCS
|
||||
lts_web_socket_client.cpp
|
||||
lts_web_socket_client.h
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY2(WS AAR SV LtsWebSocketClient SHARED ${LtsWebSocketClient_SRCS})
|
||||
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(LtsWebSocketClient
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
||||
)
|
||||
|
||||
NGL_TARGET_LINK_LIBRARIES(LtsWebSocketClient
|
||||
Qt5::Core
|
||||
LtsWebSocketCommon
|
||||
)
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
|
||||
|
||||
#include "client_connection.h"
|
||||
|
||||
#include <QWebSocket>
|
||||
|
||||
namespace LtsWebSocket
|
||||
{
|
||||
|
||||
ClientConnection::ClientConnection(QWebSocket *socket, QObject *parent)
|
||||
: QThread(parent)
|
||||
, m_socket(socket ? socket : new QWebSocket)
|
||||
, m_logger(getLogger("ClientConnection"))
|
||||
{
|
||||
}
|
||||
|
||||
ClientConnection::~ClientConnection()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Thread closed" << this;
|
||||
delete m_socket;
|
||||
qDeleteAll(m_messageQueue);
|
||||
}
|
||||
|
||||
bool ClientConnection::init()
|
||||
{
|
||||
if (m_socket == nullptr)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Initialisation failed due to an invalid socket";
|
||||
return false;
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << "Started new thread" << this;
|
||||
connect(m_socket, &QWebSocket::textMessageReceived, this, &ClientConnection::onNewTextMessageFromSocket, Qt::DirectConnection);
|
||||
connect(m_socket, &QWebSocket::connected, this, &ClientConnection::sendMessagesFromQueue);
|
||||
connect(m_socket, &QWebSocket::disconnected, this, &ClientConnection::onSocketDisconnect);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ClientConnection::addReply(ReplyMessage *message)
|
||||
{
|
||||
if (!m_socket || m_socket->state() != QAbstractSocket::ConnectedState)
|
||||
{
|
||||
m_messageQueue.enqueue(message);
|
||||
DEBUG_LOG(m_logger) << "Adding message to queue, size: " << m_messageQueue.size();
|
||||
return;
|
||||
}
|
||||
const QString msg(message->toJsonString());
|
||||
DEBUG_LOG(m_logger) << "Sending message: " << msg ;
|
||||
m_socket->sendTextMessage(msg);
|
||||
delete message;
|
||||
}
|
||||
|
||||
void ClientConnection::onNewTextMessageFromSocket(const QString &message)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Recv msg: " << message << this;
|
||||
emit newTextMessage(this, message);
|
||||
}
|
||||
|
||||
void ClientConnection::sendMessagesFromQueue()
|
||||
{
|
||||
INFO_LOG(m_logger) << "Client connected ip: " << m_socket->peerAddress().toString() << ":" << m_socket->peerPort();
|
||||
|
||||
if (m_socket->state() != QAbstractSocket::ConnectedState)
|
||||
return;
|
||||
while (!m_messageQueue.isEmpty())
|
||||
{
|
||||
ReplyMessage *message = m_messageQueue.dequeue();
|
||||
const QString msg(message->toJsonString());
|
||||
TRACE_LOG(m_logger) << "Send msg: " << msg;
|
||||
m_socket->sendTextMessage(msg);
|
||||
delete message;
|
||||
DEBUG_LOG(m_logger) << "Sent message from queue, new size: " << m_messageQueue.size();
|
||||
}
|
||||
}
|
||||
|
||||
void ClientConnection::onSocketDisconnect()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Client disconnected ip: " << m_socket->peerAddress().toString() << ":" << m_socket->peerPort();
|
||||
exit(0);
|
||||
emit disconnected(this);
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+70
@@ -0,0 +1,70 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QThread>
|
||||
#include <QtCore/QQueue>
|
||||
|
||||
#include "reply_message.h"
|
||||
#include "logger.h"
|
||||
#include <LtsWebSocket/ltswebsocketserver_export.h>
|
||||
|
||||
class QWebSocket;
|
||||
|
||||
namespace LtsWebSocket
|
||||
{
|
||||
|
||||
|
||||
|
||||
class LTSWEBSOCKETSERVER_EXPORT ClientConnection
|
||||
: public QThread
|
||||
, public ReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
|
||||
explicit ClientConnection(QWebSocket *socket, QObject *parent = nullptr);
|
||||
|
||||
|
||||
|
||||
|
||||
~ClientConnection();
|
||||
|
||||
|
||||
|
||||
bool init();
|
||||
|
||||
|
||||
|
||||
void addReply(ReplyMessage *message) override;
|
||||
|
||||
QWebSocket *webSocket() { return m_socket; }
|
||||
signals:
|
||||
|
||||
|
||||
void newTextMessage(ClientConnection *client, const QString &message);
|
||||
|
||||
|
||||
|
||||
void disconnected(ClientConnection *client);
|
||||
|
||||
|
||||
private slots:
|
||||
void onNewTextMessageFromSocket(const QString &message);
|
||||
void sendMessagesFromQueue();
|
||||
void onSocketDisconnect();
|
||||
private:
|
||||
|
||||
|
||||
void sendMessages();
|
||||
|
||||
private:
|
||||
QWebSocket *m_socket;
|
||||
QQueue<ReplyMessage *> m_messageQueue;
|
||||
|
||||
LOGGER_T m_logger;
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
Executable
+38
@@ -0,0 +1,38 @@
|
||||
|
||||
|
||||
#include "client_message.h"
|
||||
|
||||
#include "json_keys.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
|
||||
namespace LtsWebSocket
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
InvalidMessage::InvalidMessage(ReplyHandler *client, const QString &uuid, const QString &errorText)
|
||||
: AbstractClientMessage(client, QString(), 1, uuid)
|
||||
, m_errorText(errorText)
|
||||
{}
|
||||
|
||||
void InvalidMessage::process()
|
||||
{
|
||||
ErrorMessage::ErrorData errorData;
|
||||
|
||||
errorData.errorClass = 1;
|
||||
errorData.errorMessage = m_errorText;
|
||||
errorData.uuid = m_uuid;
|
||||
|
||||
m_client->addReply(new ErrorMessage(errorData));
|
||||
}
|
||||
|
||||
bool InvalidMessage::hasValidData() const
|
||||
{
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Executable
+70
@@ -0,0 +1,70 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LtsWebSocket/ltswebsocketcommon_export.h>
|
||||
#include "reply_message.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QJsonValue>
|
||||
|
||||
namespace LtsWebSocket
|
||||
{
|
||||
|
||||
|
||||
|
||||
class LTSWEBSOCKETCOMMON_EXPORT AbstractClientMessage
|
||||
{
|
||||
public:
|
||||
AbstractClientMessage(ReplyHandler *client, const QString &type, const int typeId, const QString &uuid, const QJsonValue &data = QJsonValue())
|
||||
: m_type(type)
|
||||
, m_typeId(typeId)
|
||||
, m_uuid(uuid)
|
||||
, m_data(data)
|
||||
, m_client(client)
|
||||
{}
|
||||
|
||||
virtual ~AbstractClientMessage() = default;
|
||||
|
||||
|
||||
|
||||
virtual void process() = 0;
|
||||
|
||||
|
||||
|
||||
virtual bool hasValidData() const = 0;
|
||||
|
||||
|
||||
|
||||
void reply(ReplyMessage *reply)
|
||||
{
|
||||
m_client->addReply(reply);
|
||||
}
|
||||
|
||||
protected:
|
||||
const QString m_type;
|
||||
const int m_typeId;
|
||||
const QString m_uuid;
|
||||
const QJsonValue m_data;
|
||||
ReplyHandler *m_client;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class LTSWEBSOCKETCOMMON_EXPORT InvalidMessage final : public AbstractClientMessage
|
||||
{
|
||||
public:
|
||||
explicit InvalidMessage(ReplyHandler *client, const QString &uuid, const QString &errorText);
|
||||
|
||||
void process() override;
|
||||
bool hasValidData() const override;
|
||||
|
||||
private:
|
||||
QString m_errorText;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
|
||||
|
||||
|
||||
#include "client_message_factory.h"
|
||||
|
||||
#include "client_connection.h"
|
||||
#include "json_keys.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
|
||||
namespace LtsWebSocket
|
||||
{
|
||||
|
||||
|
||||
QJsonParseError AbstractClientMessageFactory::parseMessage(const QString &message)
|
||||
{
|
||||
QJsonParseError error;
|
||||
QJsonDocument doc = QJsonDocument::fromJson(message.toUtf8(), &error);
|
||||
|
||||
if (error.error != QJsonParseError::NoError)
|
||||
return error;
|
||||
|
||||
QJsonObject obj = doc.object();
|
||||
|
||||
m_data = obj.value(JsonKeys::DATA());
|
||||
m_type = obj.value(JsonKeys::TYPE()).toString();
|
||||
m_typeId = obj.value(JsonKeys::TYPEID()).toInt();
|
||||
m_uuid = obj.value(JsonKeys::UUID_()).toString();
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
AbstractClientMessage *AbstractClientMessageFactory::checkAttributes(ReplyHandler *client,
|
||||
const QString &message) const
|
||||
{
|
||||
if (!m_uuid.isEmpty() && !m_type.isEmpty())
|
||||
return nullptr;
|
||||
if (m_uuid.isEmpty())
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Got message without uuid: " << message << "'";
|
||||
return new LtsWebSocket::InvalidMessage(client, QString(), QStringLiteral("Got message without uuid"));
|
||||
}
|
||||
WARNING_LOG(m_logger) << "Got message no type: " << message << "'";
|
||||
return new LtsWebSocket::InvalidMessage(client, m_uuid, QStringLiteral("Message has no type"));
|
||||
}
|
||||
|
||||
AbstractClientMessage *AbstractClientMessageFactory::checkResult(ReplyHandler *client,
|
||||
const QString &message,
|
||||
AbstractClientMessage *result) const
|
||||
{
|
||||
if (result == nullptr)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Could not parse message: " << message;
|
||||
result = new LtsWebSocket::InvalidMessage(client, m_uuid, QStringLiteral("Invalid type"));
|
||||
}
|
||||
|
||||
if (!result->hasValidData())
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Resulting JSon message has invalid data... " << message;
|
||||
delete result;
|
||||
result = new LtsWebSocket::InvalidMessage(client, m_uuid, QStringLiteral("Has invalid data part"));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "client_message.h"
|
||||
#include "reply_message.h"
|
||||
#include <LtsWebSocket/ltswebsocketcommon_export.h>
|
||||
|
||||
#include <QString>
|
||||
#include <QJsonParseError>
|
||||
|
||||
namespace NGL
|
||||
{
|
||||
class INGLLogger;
|
||||
}
|
||||
namespace LtsWebSocket
|
||||
{
|
||||
|
||||
|
||||
|
||||
class LTSWEBSOCKETCOMMON_EXPORT AbstractClientMessageFactory
|
||||
{
|
||||
public:
|
||||
explicit AbstractClientMessageFactory(NGL::INGLLogger &logger)
|
||||
: m_logger(logger)
|
||||
{}
|
||||
|
||||
virtual ~AbstractClientMessageFactory() {}
|
||||
|
||||
|
||||
|
||||
QJsonParseError parseMessage(const QString &message);
|
||||
|
||||
|
||||
|
||||
virtual AbstractClientMessage *createMessage(ReplyHandler *client, const QString &message) = 0;
|
||||
|
||||
protected:
|
||||
AbstractClientMessage *checkAttributes(ReplyHandler *client,
|
||||
const QString &message) const;
|
||||
AbstractClientMessage *checkResult(ReplyHandler *client,
|
||||
const QString &message,
|
||||
AbstractClientMessage *result) const;
|
||||
protected:
|
||||
QString m_type;
|
||||
int m_typeId;
|
||||
QString m_uuid;
|
||||
QJsonValue m_data;
|
||||
NGL::INGLLogger &m_logger;
|
||||
|
||||
};
|
||||
|
||||
class PongMessage final : public ReplyMessage
|
||||
{
|
||||
public:
|
||||
static QString strPong() { return QStringLiteral("pong"); }
|
||||
static int idPong() { return 2; }
|
||||
explicit PongMessage(const QString &payload)
|
||||
: ReplyMessage(strPong(), idPong(), QString())
|
||||
, m_payload(payload)
|
||||
{}
|
||||
|
||||
QString toJsonString() const override
|
||||
{
|
||||
return m_payload.isEmpty() ? strPong() : QStringLiteral("%1 %2").arg(strPong(), m_payload);
|
||||
}
|
||||
private:
|
||||
QString m_payload;
|
||||
};
|
||||
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
|
||||
|
||||
#include "connection_handler.h"
|
||||
|
||||
#include "client_connection.h"
|
||||
|
||||
#include <QtWebSockets/QWebSocket>
|
||||
|
||||
using namespace LtsWebSocket;
|
||||
|
||||
ConnectionHandler::ConnectionHandler(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_server(nullptr)
|
||||
, m_logger(getLogger("ConnectionHandler"))
|
||||
{}
|
||||
|
||||
ConnectionHandler::~ConnectionHandler()
|
||||
{
|
||||
for (auto connection : qAsConst(m_connections))
|
||||
connection->disconnect(this);
|
||||
}
|
||||
|
||||
bool ConnectionHandler::init(const QString &serviceName, unsigned short port)
|
||||
{
|
||||
if (m_server != nullptr)
|
||||
{
|
||||
m_server->disconnect();
|
||||
delete m_server;
|
||||
}
|
||||
|
||||
m_server = new QWebSocketServer(QStringLiteral("RME-") + serviceName, QWebSocketServer::NonSecureMode, this);
|
||||
|
||||
connect(m_server, &QWebSocketServer::newConnection, this, &ConnectionHandler::onNewConnection);
|
||||
connect(m_server, &QWebSocketServer::serverError, this, &ConnectionHandler::onServerError);
|
||||
|
||||
DEBUG_LOG(m_logger) << "Trying to listen ";
|
||||
if (!m_server->listen(QHostAddress::Any, port))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Not possible to listen to port " << port;
|
||||
return false;
|
||||
}
|
||||
DEBUG_LOG(m_logger) << "... ok, port " << m_server->serverPort();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ConnectionHandler::sendToAllClients(ReplyMessage *message)
|
||||
{
|
||||
for (auto connection : qAsConst(m_connections))
|
||||
connection->addReply(new ReplyMessage(*message));
|
||||
|
||||
delete message;
|
||||
}
|
||||
|
||||
void ConnectionHandler::onServerError(QWebSocketProtocol::CloseCode closeCode)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Got server error with close code " << closeCode;
|
||||
}
|
||||
|
||||
void ConnectionHandler::onNewConnection()
|
||||
{
|
||||
while (m_server->hasPendingConnections())
|
||||
{
|
||||
QWebSocket *socket = m_server->nextPendingConnection();
|
||||
|
||||
ClientConnection *newConnection = new ClientConnection(socket, this);
|
||||
connect(newConnection, &ClientConnection::destroyed, this, [this](QObject* o)
|
||||
{
|
||||
m_connections.remove(static_cast<ClientConnection*>(o));
|
||||
});
|
||||
|
||||
if (!newConnection->init())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Failed to initialise new client";
|
||||
delete newConnection;
|
||||
newConnection = nullptr;
|
||||
continue;
|
||||
}
|
||||
newConnection->start();
|
||||
|
||||
connect(newConnection, &ClientConnection::newTextMessage, this, &ConnectionHandler::newTextMessageFromClient);
|
||||
connect(newConnection, &ClientConnection::disconnected, this, &ConnectionHandler::clientDisconnected);
|
||||
connect(newConnection, &ClientConnection::finished, newConnection, &ClientConnection::deleteLater);
|
||||
|
||||
m_connections.insert(newConnection);
|
||||
emit clientConnected(newConnection);
|
||||
INFO_LOG(m_logger) << "New client connected ip: " << socket->localAddress().toString() << ":" << socket->localPort();
|
||||
}
|
||||
}
|
||||
Executable
+64
@@ -0,0 +1,64 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtNetwork/QHostAddress>
|
||||
#include <QtWebSockets/qwebsocketprotocol.h>
|
||||
#include <QtWebSockets/QWebSocketServer>
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
namespace LtsWebSocket
|
||||
{
|
||||
class MessageHandler;
|
||||
class ClientConnection;
|
||||
class ReplyMessage;
|
||||
|
||||
|
||||
|
||||
class ConnectionHandler
|
||||
: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
|
||||
explicit ConnectionHandler(QObject *parent = nullptr);
|
||||
~ConnectionHandler();
|
||||
|
||||
|
||||
|
||||
bool init(const QString &serviceName, unsigned short port);
|
||||
|
||||
|
||||
|
||||
void sendToAllClients(ReplyMessage *message);
|
||||
|
||||
|
||||
|
||||
unsigned short webSocketPort() { return m_server->serverPort(); }
|
||||
|
||||
signals:
|
||||
|
||||
|
||||
void newTextMessageFromClient(ClientConnection *client, const QString &message);
|
||||
|
||||
|
||||
|
||||
void clientDisconnected(ClientConnection *client);
|
||||
|
||||
|
||||
|
||||
void clientConnected(ClientConnection *client);
|
||||
|
||||
private slots:
|
||||
void onServerError(QWebSocketProtocol::CloseCode closeCode);
|
||||
void onNewConnection();
|
||||
|
||||
private:
|
||||
QWebSocketServer *m_server;
|
||||
QSet<ClientConnection *> m_connections;
|
||||
LOGGER_T m_logger;
|
||||
|
||||
};
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
#include <memory>
|
||||
#include <NGLLogger/INGLLogger.h>
|
||||
|
||||
#include "reply_message.h"
|
||||
|
||||
namespace LtsWebSocket
|
||||
{
|
||||
|
||||
|
||||
template<typename T>
|
||||
class DataManagerBaseDl
|
||||
{
|
||||
protected:
|
||||
|
||||
|
||||
explicit DataManagerBaseDl(const std::shared_ptr<T> &dbInterface, NGL::INGLLogger &logger)
|
||||
: m_logger(logger)
|
||||
, m_dbInterface(dbInterface)
|
||||
{}
|
||||
|
||||
|
||||
|
||||
template<typename DbType, typename MessageType>
|
||||
ReplyMessage *toBaseDataMessageFromDb(const QString &uuid) const
|
||||
{
|
||||
QVector<DbType> dataVec;
|
||||
|
||||
if (!m_dbInterface->select(dataVec))
|
||||
{
|
||||
const QString errorMessage = QStringLiteral("Error reading data from database!");
|
||||
ERROR_LOG(m_logger) << errorMessage;
|
||||
ErrorMessage::ErrorData errData;
|
||||
errData.errorMessage = errorMessage;
|
||||
errData.uuid = uuid;
|
||||
return new ErrorMessage(errData);
|
||||
}
|
||||
|
||||
return new MessageType (m_dbInterface->template toJson<DbType>(dataVec), uuid);
|
||||
}
|
||||
|
||||
protected:
|
||||
NGL::INGLLogger &m_logger;
|
||||
std::shared_ptr<T> m_dbInterface;
|
||||
};
|
||||
}
|
||||
Executable
+26
@@ -0,0 +1,26 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QString>
|
||||
|
||||
namespace LtsWebSocket
|
||||
{
|
||||
|
||||
|
||||
namespace JsonKeys
|
||||
{
|
||||
|
||||
inline QString DATA() { return QStringLiteral("data"); }
|
||||
inline QString UUID_() { return QStringLiteral("uuid"); }
|
||||
inline QString TYPE() { return QStringLiteral("type"); }
|
||||
inline QString TYPEID() { return QStringLiteral("typeId"); }
|
||||
|
||||
|
||||
inline QString ERROR_() { return QStringLiteral("error"); }
|
||||
|
||||
|
||||
inline QString ERROR_MESSAGE() { return QStringLiteral("errorMessage"); }
|
||||
inline QString ERROR_CLASS() { return QStringLiteral("errorClass"); }
|
||||
}
|
||||
}
|
||||
Executable
+32
@@ -0,0 +1,32 @@
|
||||
|
||||
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||||
|
||||
namespace LtsWebSocket
|
||||
{
|
||||
|
||||
LOGGER_T getLogger(const char *name)
|
||||
{
|
||||
static const char ns[] = "Lts.WebSocket.";
|
||||
std::string loggerName;
|
||||
const size_t len = strlen(name);
|
||||
loggerName.reserve(sizeof(ns) + len);
|
||||
loggerName.append(ns, sizeof(ns) - 1);
|
||||
loggerName.append(name, len);
|
||||
|
||||
try
|
||||
{
|
||||
return NGL::NGLLoggerBootstrap::getNGLRootLogger().
|
||||
getNGLLogger(loggerName);
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
fprintf(stderr, "Error retrieving logger: %s", ex.what());
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LtsWebSocket/ltswebsocketcommon_export.h>
|
||||
#include <NGLLogger/INGLLogger.h>
|
||||
|
||||
namespace LtsWebSocket
|
||||
{
|
||||
typedef NGL::INGLLogger &LOGGER_T;
|
||||
|
||||
LTSWEBSOCKETCOMMON_EXPORT LOGGER_T getLogger(const char *name);
|
||||
inline LOGGER_T getLogger(const QString &loggerName)
|
||||
{
|
||||
return getLogger(loggerName.toUtf8().constData());
|
||||
}
|
||||
}
|
||||
+202
@@ -0,0 +1,202 @@
|
||||
|
||||
|
||||
#include "lts_web_socket_client.h"
|
||||
|
||||
#include <QThread>
|
||||
#include <QUrl>
|
||||
#include <QWebSocket>
|
||||
|
||||
#include "client_connection.h"
|
||||
|
||||
namespace LtsWebSocket
|
||||
{
|
||||
class WebSocketHelper : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
WebSocketHelper(AbstractClientMessageFactory *messageFactory,
|
||||
LtsWebSocketClient *webSocketClient,
|
||||
NGL::INGLLogger &logger);
|
||||
~WebSocketHelper();
|
||||
|
||||
public Q_SLOTS:
|
||||
void doOpen(const QString &hostname, const unsigned short port);
|
||||
void doClose();
|
||||
void doSendTextMessage(const QString &msg);
|
||||
void onConnected();
|
||||
void onDisconnected();
|
||||
void onError(QAbstractSocket::SocketError error);
|
||||
void parseMessage(const QString &message);
|
||||
Q_SIGNALS:
|
||||
void messageParsed(AbstractClientMessage *clientMessage);
|
||||
void connected();
|
||||
void disconnected();
|
||||
void dataReceived();
|
||||
void error(QAbstractSocket::SocketError);
|
||||
private:
|
||||
AbstractClientMessageFactory *m_messageFactory;
|
||||
LtsWebSocketClient *m_webSocketClient;
|
||||
QWebSocket *m_socket;
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
|
||||
WebSocketHelper::WebSocketHelper(AbstractClientMessageFactory *messageFactory,
|
||||
LtsWebSocketClient *webSocketClient,
|
||||
NGL::INGLLogger &logger)
|
||||
: QObject()
|
||||
, m_messageFactory(messageFactory)
|
||||
, m_webSocketClient(webSocketClient)
|
||||
, m_socket(new QWebSocket(QString(), QWebSocketProtocol::VersionLatest, this))
|
||||
, m_logger(logger)
|
||||
{
|
||||
connect(m_socket, &QWebSocket::textMessageReceived, this, &WebSocketHelper::parseMessage);
|
||||
connect(m_socket, &QWebSocket::textFrameReceived, this, &WebSocketHelper::dataReceived);
|
||||
connect(m_socket, &QWebSocket::connected, this, &WebSocketHelper::onConnected);
|
||||
connect(m_socket, &QWebSocket::disconnected, this, &WebSocketHelper::onDisconnected);
|
||||
connect(m_socket, QOverload<QAbstractSocket::SocketError>::of(&QWebSocket::error), this, &WebSocketHelper::error);
|
||||
}
|
||||
|
||||
WebSocketHelper::~WebSocketHelper()
|
||||
{
|
||||
m_socket->close();
|
||||
delete m_socket;
|
||||
}
|
||||
|
||||
void WebSocketHelper::doOpen(const QString &hostname, const unsigned short port)
|
||||
{
|
||||
const QUrl url(QStringLiteral("ws://%1:%2/").arg(hostname).arg(port));
|
||||
|
||||
if (m_socket->state() == QAbstractSocket::SocketState::ConnectedState)
|
||||
{
|
||||
if (m_socket->requestUrl() != url)
|
||||
doClose();
|
||||
else
|
||||
{
|
||||
INFO_LOG(m_logger) << "Web socket to url: " << url.toDisplayString() << " is already open.";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
INFO_LOG(m_logger) << "Opening web socket to url: " << url.toDisplayString();
|
||||
m_socket->open(url);
|
||||
}
|
||||
|
||||
void WebSocketHelper::doClose()
|
||||
{
|
||||
INFO_LOG(m_logger) << "Closing web socket to url:" << m_socket->requestUrl().toDisplayString();
|
||||
m_socket->close();
|
||||
}
|
||||
|
||||
void WebSocketHelper::doSendTextMessage(const QString &msg)
|
||||
{
|
||||
if (!m_socket || m_socket->state() != QAbstractSocket::ConnectedState)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Message could not be send, socket is not connected.";
|
||||
return;
|
||||
}
|
||||
DEBUG_LOG(m_logger) << "Sending message: " << msg;
|
||||
m_socket->sendTextMessage(msg);
|
||||
}
|
||||
|
||||
void WebSocketHelper::onConnected()
|
||||
{
|
||||
INFO_LOG(m_logger) << "Connected to server url: " << m_socket->requestUrl().toDisplayString()
|
||||
<< " using local port: " << m_socket->localPort();
|
||||
emit connected();
|
||||
}
|
||||
|
||||
void WebSocketHelper::onDisconnected()
|
||||
{
|
||||
INFO_LOG(m_logger) << "Disconnected from server url: " << m_socket->requestUrl().toDisplayString();
|
||||
emit disconnected();
|
||||
}
|
||||
|
||||
void WebSocketHelper::onError(QAbstractSocket::SocketError error)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Error occured: " << error << " closing socket.";
|
||||
m_socket->close();
|
||||
}
|
||||
|
||||
void WebSocketHelper::parseMessage(const QString &message)
|
||||
{
|
||||
const QString pingMsg(QStringLiteral("ping"));
|
||||
if (message.startsWith(pingMsg))
|
||||
{
|
||||
doSendTextMessage(PongMessage(message.mid(pingMsg.size())).toJsonString());
|
||||
return;
|
||||
}
|
||||
|
||||
AbstractClientMessage *clientMessage = nullptr;
|
||||
auto result = m_messageFactory->parseMessage(message);
|
||||
if (QJsonParseError::NoError == result.error)
|
||||
clientMessage = m_messageFactory->createMessage(m_webSocketClient, message);
|
||||
else
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Could not parse incoming message: '" << message
|
||||
<< "', error: " << result.errorString();
|
||||
clientMessage = new InvalidMessage(m_webSocketClient, QString(),
|
||||
QStringLiteral("Got message which is not JSON conform (%1)").arg(result.errorString()));
|
||||
}
|
||||
if (clientMessage)
|
||||
emit messageParsed(clientMessage);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
LtsWebSocketClient::LtsWebSocketClient(AbstractClientMessageFactory *messageFactory, QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_messageFactory(messageFactory)
|
||||
, m_webSocketHelperThread(new QThread(this))
|
||||
, m_logger(getLogger("LtsWebSocketClient"))
|
||||
{
|
||||
m_webSocketHelper = new WebSocketHelper(m_messageFactory, this, m_logger);
|
||||
m_webSocketHelper->moveToThread(m_webSocketHelperThread);
|
||||
m_webSocketHelperThread->start();
|
||||
|
||||
connect(m_webSocketHelper, &WebSocketHelper::connected, this, &LtsWebSocketClient::connected);
|
||||
connect(m_webSocketHelper, &WebSocketHelper::disconnected, this, &LtsWebSocketClient::disconnected);
|
||||
connect(m_webSocketHelper, &WebSocketHelper::dataReceived, this, &LtsWebSocketClient::dataReceived);
|
||||
connect(m_webSocketHelper, &WebSocketHelper::messageParsed, this, &LtsWebSocketClient::onNewClientMessage);
|
||||
|
||||
connect(this, &LtsWebSocketClient::onOpen, m_webSocketHelper, &WebSocketHelper::doOpen);
|
||||
connect(this, &LtsWebSocketClient::onClose, m_webSocketHelper, &WebSocketHelper::doClose);
|
||||
connect(this, &LtsWebSocketClient::onSendTextMessage, m_webSocketHelper, &WebSocketHelper::doSendTextMessage);
|
||||
}
|
||||
|
||||
LtsWebSocketClient::~LtsWebSocketClient()
|
||||
{
|
||||
m_webSocketHelper->disconnect(this);
|
||||
m_webSocketHelperThread->quit();
|
||||
m_webSocketHelperThread->wait();
|
||||
delete m_webSocketHelper;
|
||||
}
|
||||
|
||||
void LtsWebSocketClient::open(const QString &hostname, const unsigned short port)
|
||||
{
|
||||
emit onOpen(hostname, port);
|
||||
}
|
||||
|
||||
void LtsWebSocketClient::close()
|
||||
{
|
||||
emit onClose();
|
||||
}
|
||||
|
||||
void LtsWebSocketClient::addReply(ReplyMessage *message)
|
||||
{
|
||||
const QString msg(message->toJsonString());
|
||||
emit onSendTextMessage(msg);
|
||||
delete message;
|
||||
}
|
||||
|
||||
void LtsWebSocketClient::onNewClientMessage(AbstractClientMessage *clientMessage)
|
||||
{
|
||||
if (!clientMessage)
|
||||
return;
|
||||
clientMessage->process();
|
||||
delete clientMessage;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#include "lts_web_socket_client.moc"
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QAbstractSocket>
|
||||
|
||||
#include <LtsWebSocket/ltswebsocketclient_export.h>
|
||||
#include "client_message_factory.h"
|
||||
#include "logger.h"
|
||||
|
||||
|
||||
class QThread;
|
||||
namespace LtsWebSocket
|
||||
{
|
||||
class WebSocketHelper;
|
||||
|
||||
|
||||
|
||||
class LTSWEBSOCKETCLIENT_EXPORT LtsWebSocketClient
|
||||
: public QObject
|
||||
, public ReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
|
||||
explicit LtsWebSocketClient(AbstractClientMessageFactory *messageFactory, QObject *parent = nullptr);
|
||||
~LtsWebSocketClient();
|
||||
|
||||
|
||||
|
||||
void open(const QString &hostname, const unsigned short port);
|
||||
|
||||
|
||||
|
||||
void close();
|
||||
|
||||
|
||||
|
||||
void addReply(ReplyMessage *message) override;
|
||||
|
||||
signals:
|
||||
void connected();
|
||||
void disconnected();
|
||||
void dataReceived();
|
||||
|
||||
private slots:
|
||||
|
||||
|
||||
void onNewClientMessage(AbstractClientMessage *clientMessage);
|
||||
|
||||
signals:
|
||||
void onOpen(const QString &hostname, const unsigned short port);
|
||||
void onClose();
|
||||
void onSendTextMessage(const QString &msg);
|
||||
|
||||
private:
|
||||
AbstractClientMessageFactory *m_messageFactory;
|
||||
|
||||
QThread *m_webSocketHelperThread;
|
||||
WebSocketHelper *m_webSocketHelper;
|
||||
|
||||
|
||||
LOGGER_T m_logger;
|
||||
};
|
||||
}
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
|
||||
|
||||
#include "lts_web_socket_server.h"
|
||||
|
||||
#include "connection_handler.h"
|
||||
#include "client_connection.h"
|
||||
#include <QTimer>
|
||||
|
||||
namespace LtsWebSocket
|
||||
{
|
||||
|
||||
LtsWebSocketServer::LtsWebSocketServer(AbstractClientMessageFactory *messageFactory, QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_queueTimer(new QTimer(this))
|
||||
, m_messageFactory(messageFactory)
|
||||
, m_connectionHandler(nullptr)
|
||||
, m_logger(getLogger("LtsWebSocketServer"))
|
||||
{
|
||||
connect(m_queueTimer, &QTimer::timeout,
|
||||
this, &LtsWebSocketServer::onQueueTimerTimeout);
|
||||
|
||||
m_queueTimer->setSingleShot(true);
|
||||
}
|
||||
|
||||
LtsWebSocketServer::~LtsWebSocketServer() = default;
|
||||
|
||||
bool LtsWebSocketServer::init(const QString &serviceName, const unsigned short port)
|
||||
{
|
||||
m_connectionHandler.reset(new ConnectionHandler(this));
|
||||
|
||||
if (!m_connectionHandler->init(serviceName, port))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not init m_connectionHandler with servicename: " << serviceName << ((port == 0) ? QStringLiteral(" random port") : QStringLiteral(" port: ") + QString::number(port));
|
||||
m_connectionHandler.reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
connect(m_connectionHandler.get(), &ConnectionHandler::newTextMessageFromClient, this, &LtsWebSocketServer::onNewTextMessage);
|
||||
connect(m_connectionHandler.get(), &ConnectionHandler::clientDisconnected, this, &LtsWebSocketServer::clientDisconnected);
|
||||
connect(m_connectionHandler.get(), &ConnectionHandler::clientConnected, this, &LtsWebSocketServer::clientConnected);
|
||||
|
||||
m_queueTimer->start(m_messageDelay);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LtsWebSocketServer::init(const QString &serviceName, const QPair<quint16, quint16> &portRange)
|
||||
{
|
||||
if (portRange.first < 1025 || portRange.first > portRange.second)
|
||||
return init(serviceName);
|
||||
|
||||
for (quint16 currentPort = portRange.first; currentPort <= portRange.second; ++ currentPort)
|
||||
{
|
||||
if (init(serviceName, currentPort))
|
||||
return true;
|
||||
}
|
||||
|
||||
return init(serviceName);
|
||||
}
|
||||
|
||||
void LtsWebSocketServer::sendToAllClients(ReplyMessage *message)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Sending message to all clients: " << message->toJsonString();
|
||||
m_connectionHandler->sendToAllClients(message);
|
||||
}
|
||||
|
||||
unsigned short LtsWebSocketServer::webSocketPort() const
|
||||
{
|
||||
return m_connectionHandler->webSocketPort();
|
||||
}
|
||||
|
||||
void LtsWebSocketServer::setMessageDelay(qint32 delay)
|
||||
{
|
||||
m_messageDelay = delay;
|
||||
}
|
||||
|
||||
void LtsWebSocketServer::onNewTextMessage(ReplyHandler *client, const QString &message)
|
||||
{
|
||||
const QString pingMsg(QStringLiteral("ping"));
|
||||
if (message.startsWith(pingMsg))
|
||||
{
|
||||
client->addReply(new PongMessage(message.mid(pingMsg.size())));
|
||||
return;
|
||||
}
|
||||
DEBUG_LOG(m_logger) << "Got new message: " << message;
|
||||
|
||||
m_messageQueue.append({client, message});
|
||||
|
||||
if (!m_queueTimer->isActive())
|
||||
m_queueTimer->start(m_messageDelay);
|
||||
}
|
||||
|
||||
void LtsWebSocketServer::onQueueTimerTimeout()
|
||||
{
|
||||
if (m_messageQueue.isEmpty())
|
||||
return;
|
||||
|
||||
MessageCredentials credentials = m_messageQueue.takeFirst();
|
||||
AbstractClientMessage *clientMessage = nullptr;
|
||||
auto result = m_messageFactory->parseMessage(credentials.message);
|
||||
|
||||
if (QJsonParseError::NoError == result.error)
|
||||
clientMessage = m_messageFactory->createMessage(credentials.client, credentials.message);
|
||||
else
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Could not parse incoming message: '" << credentials.message << "', error: " << result.errorString();
|
||||
|
||||
clientMessage = new InvalidMessage(credentials.client, QString(), QStringLiteral("Got message which is not JSON conform"));
|
||||
}
|
||||
|
||||
if (clientMessage)
|
||||
clientMessage->process();
|
||||
|
||||
delete clientMessage;
|
||||
|
||||
m_queueTimer->start(m_messageDelay);
|
||||
}
|
||||
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QObject>
|
||||
|
||||
#include <LtsWebSocket/ltswebsocketserver_export.h>
|
||||
#include "client_message_factory.h"
|
||||
#include "logger.h"
|
||||
#include <memory>
|
||||
#include <QQueue>
|
||||
|
||||
class QTimer;
|
||||
|
||||
namespace LtsWebSocket
|
||||
{
|
||||
class ConnectionHandler;
|
||||
class ClientConnection;
|
||||
|
||||
|
||||
|
||||
class LTSWEBSOCKETSERVER_EXPORT LtsWebSocketServer
|
||||
: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
|
||||
explicit LtsWebSocketServer(AbstractClientMessageFactory *messageFactory, QObject *parent = nullptr);
|
||||
virtual ~LtsWebSocketServer();
|
||||
|
||||
|
||||
|
||||
bool init(const QString &serviceName, const unsigned short port = 0);
|
||||
|
||||
|
||||
|
||||
bool init(const QString &serviceName, const QPair<quint16, quint16> &portRange);
|
||||
|
||||
|
||||
|
||||
void sendToAllClients(ReplyMessage *message);
|
||||
|
||||
|
||||
|
||||
unsigned short webSocketPort() const;
|
||||
|
||||
|
||||
|
||||
void setMessageDelay(qint32 delay);
|
||||
signals:
|
||||
|
||||
|
||||
void clientDisconnected(ClientConnection *client);
|
||||
|
||||
|
||||
|
||||
void clientConnected(ClientConnection *client);
|
||||
|
||||
private slots:
|
||||
|
||||
|
||||
void onNewTextMessage(ReplyHandler *client, const QString &message);
|
||||
|
||||
|
||||
|
||||
void onQueueTimerTimeout();
|
||||
|
||||
private:
|
||||
struct MessageCredentials
|
||||
{
|
||||
ReplyHandler *client {nullptr};
|
||||
QString message;
|
||||
|
||||
MessageCredentials(ReplyHandler *client, const QString &message)
|
||||
: client(client)
|
||||
, message(message)
|
||||
{}
|
||||
};
|
||||
|
||||
QQueue<MessageCredentials> m_messageQueue;
|
||||
QTimer *m_queueTimer { nullptr };
|
||||
AbstractClientMessageFactory *m_messageFactory { nullptr };
|
||||
std::unique_ptr<ConnectionHandler> m_connectionHandler;
|
||||
qint32 m_messageDelay { 0 };
|
||||
LOGGER_T m_logger;
|
||||
};
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
|
||||
|
||||
|
||||
namespace LtsWebSocketServer
|
||||
{
|
||||
class ReplyMessage;
|
||||
|
||||
|
||||
|
||||
class MessageHandler
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
virtual void addMessage(ReplyMessage *message) = 0;
|
||||
};
|
||||
}
|
||||
Executable
+41
@@ -0,0 +1,41 @@
|
||||
|
||||
|
||||
|
||||
#include "reply_message.h"
|
||||
|
||||
#include "json_keys.h"
|
||||
|
||||
#include <QUuid>
|
||||
|
||||
namespace LtsWebSocket
|
||||
{
|
||||
|
||||
|
||||
QString ReplyMessage::toJsonString() const
|
||||
{
|
||||
return QString::fromUtf8(QJsonDocument(m_jsonRepresentation).toJson(QJsonDocument::Compact));
|
||||
}
|
||||
|
||||
ReplyMessage::ReplyMessage(const QString &type, const int typeId, const QString &uuid)
|
||||
{
|
||||
m_jsonRepresentation.insert(JsonKeys::TYPE(), type);
|
||||
m_jsonRepresentation.insert(JsonKeys::TYPEID(), typeId);
|
||||
|
||||
if (!uuid.isEmpty())
|
||||
m_jsonRepresentation.insert(JsonKeys::UUID_(), uuid);
|
||||
}
|
||||
|
||||
|
||||
|
||||
ErrorMessage::ErrorMessage(const ErrorMessage::ErrorData &data)
|
||||
: ReplyMessage(JsonKeys::ERROR_(), -1, QUuid::createUuid().toString())
|
||||
{
|
||||
m_jsonRepresentation.insert(JsonKeys::DATA(),
|
||||
QJsonObject({{JsonKeys::UUID_(), data.uuid},
|
||||
{JsonKeys::ERROR_CLASS(), data.errorClass},
|
||||
{JsonKeys::ERROR_MESSAGE(), data.errorMessage}
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Executable
+70
@@ -0,0 +1,70 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LtsWebSocket/ltswebsocketcommon_export.h>
|
||||
|
||||
#include <QString>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonParseError>
|
||||
|
||||
namespace LtsWebSocket
|
||||
{
|
||||
|
||||
|
||||
|
||||
class LTSWEBSOCKETCOMMON_EXPORT ReplyMessage
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
virtual ~ReplyMessage() = default;
|
||||
|
||||
|
||||
|
||||
virtual QString toJsonString() const;
|
||||
|
||||
QJsonObject json() const { return m_jsonRepresentation; }
|
||||
|
||||
protected:
|
||||
ReplyMessage() = default;
|
||||
ReplyMessage(const QString &type, const int typeId, const QString &uuid);
|
||||
|
||||
protected:
|
||||
QJsonObject m_jsonRepresentation;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class LTSWEBSOCKETCOMMON_EXPORT ReplyHandler
|
||||
{
|
||||
public:
|
||||
virtual ~ReplyHandler() = default;
|
||||
|
||||
|
||||
virtual void addReply(ReplyMessage *message) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class LTSWEBSOCKETCOMMON_EXPORT ErrorMessage final
|
||||
: public ReplyMessage
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
struct ErrorData
|
||||
{
|
||||
int errorClass = 0;
|
||||
QString uuid;
|
||||
QString errorMessage;
|
||||
};
|
||||
|
||||
|
||||
|
||||
explicit ErrorMessage(const ErrorData &data);
|
||||
};
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user