Files
qt6-migration-pipeline/Lts/Common/LtsProjectionWorkstation/lts_projection_workstation.cpp
T

248 lines
8.1 KiB
C++
Executable File

#include "lts_projection_workstation.h"
#include "WebSocket/message_factory.h"
#include "WebSocket/json_keys.h"
#include <LtsWebSocket/lts_web_socket_server.h>
#include <LtsSession/lts_session_data.h>
#include <nglsettings/nglsettings_connections.h>
#include <QGuiApplication>
#include <QUuid>
#include <QWebSocket>
#include <QTimer>
namespace LtsProjectionWorkstation
{
static LtsProjectionWorkstation *s_ltsProjectionWorkstation = nullptr;
LtsProjectionWorkstation *LtsProjectionWorkstation::getInstance()
{
if (!s_ltsProjectionWorkstation)
{
s_ltsProjectionWorkstation = new LtsProjectionWorkstation;
qAddPostRoutine(&cleanupLtsProjectionWorkstation);
}
return s_ltsProjectionWorkstation;
}
void LtsProjectionWorkstation::cleanupLtsProjectionWorkstation()
{
delete s_ltsProjectionWorkstation;
s_ltsProjectionWorkstation = nullptr;
}
bool LtsProjectionWorkstation::hasInstance()
{
return !!s_ltsProjectionWorkstation;
}
LtsProjectionWorkstation::LtsProjectionWorkstation(QObject *parent)
: QObject(parent)
, m_logger(getLogger("LtsProjetionWorkstation"))
, m_messageFactory(new MessageFactory(this, m_logger))
, m_webSocketServer(new LtsWebSocket::LtsWebSocketServer(m_messageFactory, this))
, m_pendingLoginRequest(nullptr)
, m_vncManager(new VncServerManager(m_logger, this))
{
connect(m_webSocketServer, &LtsWebSocket::LtsWebSocketServer::clientDisconnected,
this, &LtsProjectionWorkstation::clientDisconnected);
connect(m_webSocketServer, &LtsWebSocket::LtsWebSocketServer::clientConnected,
this, &LtsProjectionWorkstation::clientConnected);
int port = NGL::Connections::port(NGL::Connections::eConnection::PWS_WEBSOCKET);
if (m_webSocketServer->init(QStringLiteral("LtsProjectionWorkstation"), port))
{
if (m_vncManager->init(qApp->screens()))
m_vncManager->startScreens();
}
}
LtsProjectionWorkstation::~LtsProjectionWorkstation()
{
delete m_vncManager;
delete m_messageFactory;
delete m_webSocketServer;
}
LoginInformation LtsProjectionWorkstation::pendingLoginRequest()
{
if (!m_pendingLoginRequest)
return {};
LoginInformation result = *m_pendingLoginRequest;
INFO_LOG(m_logger) << " reset pendingLoginRequest..";
delete m_pendingLoginRequest;
m_pendingLoginRequest = nullptr;
return result;
}
void LtsProjectionWorkstation::handleMessage(LtsWebSocket::AbstractClientMessage *message)
{
CTS::LoginRequest *login = dynamic_cast<CTS::LoginRequest *>(message);
if (login)
{
INFO_LOG(m_logger) << "Login request received!"
<< ", login->userId()=" << login->userId()
<< " with login->priority()=" << login->priority()
<< " ;;; m_lastLoginRequest.m_userId=" << m_lastLoginRequest.m_userId
<< ", m_priority=" << m_lastLoginRequest.m_priority;
if (login->userId() > 0 && login->priority() > 0 && login->exerciseId() > 0)
{
if ( login->userId() == m_lastLoginRequest.m_userId ||
(login->priority() > m_lastLoginRequest.m_priority)
)
{
m_webSocketServer->sendToAllClients( (new STC::DedicatedDisconnect(QUuid::createUuid().toString(), login->userId()))->toReplyMessage() );
DEBUG_LOG(m_logger) << "Login request received and DedicatedDisconnect distributed, wait some seconds...";
int i=0;
while(i<20)
{
DEBUG_LOG(m_logger) << "Login request received and DedicatedDisconnect distributed, wait some seconds...i=" << i;
qApp->processEvents(QEventLoop::AllEvents, 50);
QThread::msleep(50);
++i;
}
INFO_LOG(m_logger) << "Login request received and DedicatedDisconnect distributed, wait some seconds... done";
login->addReply((new STC::LoginRequestReply(QUuid::createUuid().toString(),
STC::LoginRequestReply::LoginSuccessful,
login->userId(),
m_vncManager->screens())
)->toReplyMessage());
m_lastLoginRequest.m_userId = login->userId();
m_lastLoginRequest.m_priority = login->priority();
m_lastLoginRequest.m_exerciseId = login->exerciseId();
m_lastLoginRequest.m_settingsData = login->settingsData();
slotLoginRequestReceived(login->userId(), login->exerciseId());
INFO_LOG(m_logger) << "Valid login request received -> userId: " << login->userId()
<< " priority: " << login->priority()
<< " exerciseId: " << login->exerciseId();
DEBUG_LOG(m_logger) << "Logging in now!";
}
else
{
login->addReply((new STC::LoginRequestReply(QUuid::createUuid().toString(),
STC::LoginRequestReply::OtherUser,
m_lastLoginRequest.m_userId,
QVector<VncScreen>())
)->toReplyMessage());
DEBUG_LOG(m_logger) << "Higher prioritized login received -> userId: " << login->userId()
<< " priority: " << login->priority()
<< " exerciseId: " << login->exerciseId();
DEBUG_LOG(m_logger) << "Last login data was -> userId: " << m_lastLoginRequest.m_userId
<< " priority: " << m_lastLoginRequest.m_priority
<< " exerciseId: " << m_lastLoginRequest.m_exerciseId;
}
}
else
ERROR_LOG(m_logger) << "invalid login request received -> userId: " << login->userId()
<< " priority: " << login->priority()
<< " exerciseId: " << login->exerciseId();
return;
}
CTS::LogoutRequest *logout = dynamic_cast<CTS::LogoutRequest *>(message);
if (logout)
{
DEBUG_LOG(m_logger) << "Logging out now!";
slotLogoutRequestReceived();
return;
}
CTS::DisconnectRequest *discon = dynamic_cast<CTS::DisconnectRequest *>(message);
if (discon)
{
int disconnectingUserId = discon->userId();
INFO_LOG(m_logger) << "Disconnecting now! "
<< ", disconnectingUserId=" << disconnectingUserId
<< ", m_pendingLoginRequest=" << m_pendingLoginRequest;
m_lastLoginRequest = LoginInformation();
return;
}
}
void LtsProjectionWorkstation::slotLoginRequestReceived(int userId, int exerciseId)
{
INFO_LOG(m_logger) << "slotLoginRequestReceived.."
<< ", userId=" << userId
<< ", exerciseId=" << exerciseId;
delete m_pendingLoginRequest;
m_pendingLoginRequest = new LoginInformation(m_lastLoginRequest);
emit signalLoginRequestReceived(userId, exerciseId);
}
void LtsProjectionWorkstation::slotLogoutRequestReceived()
{
emit signalLogoutRequestReceived();
}
void LtsProjectionWorkstation::slotLogoffDone()
{
if (hasPendingLoginRequest())
return;
for (LtsWebSocket::ClientConnection *con : qAsConst(m_connections))
con->webSocket()->close();
}
void LtsProjectionWorkstation::clientDisconnected(LtsWebSocket::ClientConnection *client)
{
INFO_LOG(m_logger) << LOGFUNCTION << " START"
<< ", m_connections.size = " << m_connections.size();
m_connections.removeOne(client);
if ( m_connections.size() == 0 && (m_lastLoginRequest.m_userId != 0 || m_lastLoginRequest.m_priority != 0))
{
INFO_LOG(m_logger) << LOGFUNCTION << " reset m_lastLoginRequest";
m_lastLoginRequest = LoginInformation();
}
INFO_LOG(m_logger) << LOGFUNCTION << " END"
<< ", m_connections.size = " << m_connections.size();
}
void LtsProjectionWorkstation::clientConnected(LtsWebSocket::ClientConnection *client)
{
m_connections.append(client);
}
void LtsProjectionWorkstation::setProjectionOperatorPreset(const QString &operatorName, const QString &operatorPassword)
{
m_projectionOperatorPreset.first = operatorName;
m_projectionOperatorPreset.second = operatorPassword;
}
}