#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; } void MultiThreadServer::incomingConnection(qintptr socketDesriptor) { ClientHandler* newClient = new ClientHandler; connect(this,&MultiThreadServer::sigInitClient,newClient,&ClientHandler::initialize,Qt::AutoConnection); 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 *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); else emit signal_sendPacketToAllClients(PacketType::FREE); 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(); }