#include "multithreadserver.h" MultiThreadServer::MultiThreadServer(UpdateController *updateController, DocsUpdater *docsUpdater,ProcessingSystem *processingSystem, DataParser *dataParser,qint16 hostPort, QObject *parent ): QTcpServer(parent), mutex(nullptr), clientsMap(nullptr), hostPort(hostPort), processingSystem(processingSystem), updateController(updateController), docsUpdater(docsUpdater), dataParser(dataParser), stateServer(stoped), stateBlockAutorization(blocked) { qDebug() << "MultiThreadServer init thread ID " << QThread::currentThreadId(); clientsMap = new QMap; mutex = new QMutex; connect(this, &MultiThreadServer::signal_updateDocsXML, docsUpdater, &DocsUpdater::slot_updateDocsXML); } MultiThreadServer::~MultiThreadServer() { delete mutex; delete clientsMap; } void MultiThreadServer::incomingConnection(qintptr socketDesriptor) { ClientHandler* newClient = new ClientHandler; connect(newClient,&ClientHandler::signal_updateDocsXML,this,&MultiThreadServer::slot_UpdateDocs); //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, getMutex()); newClient->initialize(socketDesriptor,updateController,dataParser, getMutex()); //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) { if(!listen(QHostAddress::Any, hostPort)) { stateServer = stoped; emit signal_StateServer(stateServer, stateBlockAutorization); Logger::instance().log("SERVER: start ERROR"); return false; } else { stateServer = started; slot_BlockAutorization(false, "SERVER", "StopServer"); emit signal_StateServer(stateServer, stateBlockAutorization); 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"); emit signal_StateServer(stateServer, stateBlockAutorization); Logger::instance().log("SERVER: stop OK"); return true; } else return false; } QMap *MultiThreadServer::getClientsMap() const { return clientsMap; } QStringList MultiThreadServer::getClientFullNameList() { QStringList list; for(ClientHandler* handler : *getClientsMap()) { QString clientFullName = handler->getClient()->getFullName(); list.append(clientFullName); } return list; } void MultiThreadServer::updateClientList() { emit signal_UpdateListClients(getClientFullNameList()); } 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"); emit signal_UpdateListClients(getClientFullNameList()); processingSystem->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::slot_StartServer() { startServer(); } void MultiThreadServer::slot_StopServer() { stopServer(); } void MultiThreadServer::slot_UpdateDocs() { emit signal_updateDocsXML(); } void MultiThreadServer::removeClient(int idSocket) { clientsMap->remove(idSocket); emit signal_UpdateListClients(getClientFullNameList()); } void MultiThreadServer::addClient(qintptr descriptor, ClientHandler *client) { (*clientsMap)[descriptor] = client; emit signal_UpdateListClients(getClientFullNameList()); }