120 lines
3.5 KiB
C++
Executable File
120 lines
3.5 KiB
C++
Executable File
|
|
|
|
#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);
|
|
}
|
|
|
|
}
|