248 lines
8.1 KiB
C++
Executable File
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;
|
|
}
|
|
|
|
}
|