Files
RRJServer/LibServer/multithreadserver/multithreadserver.cpp

274 lines
7.5 KiB
C++

#include "multithreadserver.h"
MultiThreadServer::MultiThreadServer(ServerLMSWidget *widget,UpdateController *updateController,ProcessingSystem *processingSystem,
DataParser *dataParser,qint16 hostPort, QObject *parent ):
QTcpServer(parent),
serverLmsWidget(widget),
hostPort(hostPort),
processingSystem(processingSystem),
updateController(updateController),
dataParser(dataParser),
stateServer(stoped),
stateBlockAutorization(blocked)
{
clientsMap = new QMap<int,ClientHandler*>;
}
void MultiThreadServer::incomingConnection(qintptr socketDesriptor)
{
ClientHandler* newClient = new ClientHandler;
connect(this,&MultiThreadServer::sigInitClient,newClient,&ClientHandler::initialize, Qt::AutoConnection/*Qt::DirectConnection*/);
connect(newClient,&ClientHandler::sigClientDisconnected,this,&MultiThreadServer::slotDisconnectClient,Qt::AutoConnection);
emit sigInitClient(socketDesriptor,serverLmsWidget,updateController,dataParser);
disconnect(this,&MultiThreadServer::sigInitClient,newClient,&ClientHandler::initialize);
addClient(socketDesriptor,newClient);
//Logger::instance().log("To Client: " + QString(SERVER_HELLO));
//Отправляем состояние блокировки
/*
if(getStateBlockAutorization() == EStateBlockAutorization::blocked)
newClient->sendPacketType(PacketType::BUSY);
else
newClient->sendPacketType(PacketType::FREE);*/
}
bool MultiThreadServer::startServer()
{
if(stateServer == stoped)
{
//connect(tcpServer, &QTcpServer::newConnection, this, &ServerLMSWidget::slotNewConnection,Qt::AutoConnection);
if(!listen(QHostAddress::Any, hostPort))
{
stateServer = stoped;
Logger::instance().log("SERVER: start ERROR");
return false;
}
else
{
stateServer = started;
slot_BlockAutorization(false, "SERVER", "StopServer");
Logger::instance().log("SERVER: start OK");
return true;
}
}
else
return false;
}
bool MultiThreadServer::stopServer()
{
if(stateServer == started)
{
disableClients();
//Закрываем сервер
close();
stateServer = stoped;
slot_BlockAutorization(true, "SERVER", "StopServer");
Logger::instance().log("SERVER: stop OK");
return true;
}
else
return false;
}
QMap<int, ClientHandler *> *MultiThreadServer::getClientsMap() const
{
return clientsMap;
}
void MultiThreadServer::updateClientList()
{
serverLmsWidget->slot_UpdateListClients();
}
void MultiThreadServer::disableClients()
{
QByteArray arrayAnswer = dataParser->ClientAnswer()->notify(NOTIFY_SERVER_END);
//Закрываем все открытые сокеты
foreach(int idSocket, clientsMap->keys())
{
ClientHandler* handler = (*clientsMap)[idSocket];
//Фиксируем время выхода Юнити-клиента
if(handler->getClient()->getClientType() == TypeClientAutorization::TYPE_UNITY_CLIENT)
{
processingSystem->processingExitUnityClient(handler);
}
handler->sigSendXmlAnswer(arrayAnswer, PacketType::TYPE_XMLANSWER);
QString str = QString(arrayAnswer);
QString fullName = handler->getClient()->getFullName();
processingSystem->processingClientDeAutorization(handler->getClient()->getLogin());
slot_BlockAutorization(false, fullName, "DisableClient");
handler->sigSocketClose();
//clientsMap.remove(idSocket);
removeClient(idSocket);
}
}
void MultiThreadServer::slotDisconnectClient(QString peerAddress, QString peerPort)
{
QString login = "";
qDebug() << peerAddress << " " << peerPort << " " << "disconnect";
//Проходим все открытые сокеты, ищем нужный
foreach(int idSocket, clientsMap->keys())
{
ClientHandler *client = (*clientsMap)[idSocket];
if(client->getClient()->getAddress() == peerAddress && client->getClient()->getPort() == peerPort)
{
login = client->getClient()->getLogin();
ClientDeAutorization clientDeAutorization;
clientDeAutorization.Login = login;
//QString fullName = client->getClient()->getFullName();
processingSystem->processingClientDeAutorization(client, clientDeAutorization);
//slot_BlockAutorization(false, fullName, "DisconnectClient");
removeClient(idSocket);
delete client;
continue;
}
}
emit signalStopSendFile();
Logger::instance().log("SERVER: Client " + login + " disconnected");
serverLmsWidget->slot_UpdateListClients();
serverLmsWidget->getProcessingSystem()->processingClientDeAutorization(login);
}
bool MultiThreadServer::slot_BlockAutorization(bool block, QString whoFullName, QString type)
{
bool res = false;
bool blockRes = false;
QString key = whoFullName + " [type:" + type + "]";
QString strTypes = "";
if(block)
{
if(whoFullName == "SERVER")
{
if(type == "StopServer")
{
blockersMap.clear();
}
this->blockAutorization();
blockersMap.insert(key, type);
blockRes = true;
res = true;
}
else
{
bool flExist = false;
foreach(QString keyLocal, blockersMap.keys())
{
if(blockersMap[keyLocal] == type)
{
flExist = true;
break;
}
}
if(!flExist)
{
this->blockAutorization();
blockersMap.insert(key, type);
blockRes = true;
res = true;
}
else
{
if(!blockersMap.count())
blockRes = false;
else
blockRes = true;
res = false;
}
}
}
else
{
if(type == "DeAuthorizationInstructor")
{
QStringList listKeyForDel;
for(QString keyLocal : blockersMap.keys())
{
if(keyLocal.contains(whoFullName))
listKeyForDel.append(keyLocal);
}
for(QString keyLocal : listKeyForDel)
{
blockersMap.take(keyLocal);
}
}
else
{
blockersMap.take(key);
}
if(!blockersMap.count())
{
this->unBlockAutorization();
blockRes = false;
}
else
blockRes = true;
res = true;
}
if(res)
{
/**/
if(blockRes)
emit signal_sendPacketToAllClients(PacketType::BUSY, true);
else
emit signal_sendPacketToAllClients(PacketType::FREE, true);
for(QString keyLocal : blockersMap.keys())
{
if(strTypes != "")
strTypes += ", ";
strTypes += (blockersMap[keyLocal]);
}
emit signal_BlockAutorizationIndicate(block, key, strTypes);
}
return res;
}
void MultiThreadServer::removeClient(int idSocket)
{
clientsMap->remove(idSocket);
serverLmsWidget->slot_UpdateListClients();
}
void MultiThreadServer::addClient(qintptr descriptor, ClientHandler *client)
{
(*clientsMap)[descriptor] = client;
serverLmsWidget->slot_UpdateListClients();
}