File indexing completed on 2024-05-05 05:40:33
0001 #include "network/rserver.h" 0002 #include <QDebug> 0003 #include <QMessageLogger> 0004 #include <network/serverconnectionmanager.h> 0005 0006 #include "network/timeaccepter.h" 0007 #include "network/upnp/upnpnat.h" 0008 0009 RServer::RServer(const QMap<QString, QVariant>& parameter, bool internal, QObject* parent) 0010 : QTcpServer(parent), m_corConnection(new TimeAccepter()), m_data(parameter),m_internal(internal) 0011 { 0012 if(m_data.contains("ThreadCount")) 0013 m_threadCount= m_data.value("ThreadCount", m_threadCount).toInt(); 0014 connect(this, &RServer::portChanged, this, &RServer::runUpnpNat); 0015 runUpnpNat(); 0016 } 0017 0018 RServer::~RServer() 0019 { 0020 emit eventOccured(QStringLiteral("Server Destructor"), LogController::Debug); 0021 for(auto& info : m_threadPool) 0022 { 0023 info.m_thread->quit(); 0024 info.m_thread->wait(1000); 0025 } 0026 } 0027 0028 void RServer::runUpnpNat() 0029 { 0030 auto nat= new UpnpNat(this); 0031 nat->init(5, 10); 0032 connect(nat, &UpnpNat::discoveryEnd, this, [this, nat](bool b) { 0033 0034 qDebug() << "discover ends" << nat; 0035 if(b) 0036 nat->addPortMapping("Roliserver", nat->localIp(), m_port, m_port, "TCP"); 0037 }); 0038 connect(nat, &UpnpNat::statusChanged, this, [this, nat]() { 0039 if(nat->status() == UpnpNat::NAT_STAT::NAT_ADD) 0040 { 0041 emit eventOccured(tr("[Upnp] Port mapping has been done"), LogController::LogLevel::Features); 0042 nat->deleteLater(); 0043 } 0044 }); 0045 0046 connect(nat, &UpnpNat::lastErrorChanged, this, 0047 [this, nat]() { emit eventOccured(nat->lastError(), LogController::LogLevel::Error); }); 0048 0049 nat->discovery(); 0050 } 0051 0052 bool RServer::listen() 0053 { 0054 if(!QTcpServer::listen(QHostAddress::Any, m_port)) 0055 { 0056 setState(RServer::Error); 0057 return false; 0058 } 0059 emit eventOccured(QStringLiteral("Start Listening"), LogController::Info); 0060 0061 m_connectionsManager.reset(new ServerConnectionManager(m_data)); 0062 m_updater.reset(new ServerManagerUpdater(m_connectionsManager.get(), m_internal)); 0063 m_connectionThread.reset(new QThread); 0064 0065 connect(this, &RServer::finished, m_connectionsManager.get(), &ServerConnectionManager::quit, Qt::QueuedConnection); 0066 connect(this, &RServer::accepting, m_connectionsManager.get(), &ServerConnectionManager::accept, 0067 Qt::QueuedConnection); 0068 connect(m_connectionsManager.get(), &ServerConnectionManager::finished, this, &RServer::complete, 0069 Qt::QueuedConnection); 0070 0071 for(int i= 0; i < m_threadCount; ++i) 0072 { 0073 ThreadInfo info{new QThread(this), 0}; 0074 m_threadPool.append(info); 0075 info.m_thread->start(); 0076 } 0077 0078 m_connectionsManager->moveToThread(m_connectionThread.get()); 0079 m_updater->moveToThread(m_connectionThread.get()); 0080 0081 m_connectionThread->start(); 0082 0083 setState(RServer::Listening); 0084 0085 return true; 0086 } 0087 0088 void RServer::close() 0089 { 0090 emit finished(); 0091 QTcpServer::close(); 0092 setState(RServer::Stopped); 0093 } 0094 0095 qint64 RServer::port() 0096 { 0097 return m_port; 0098 } 0099 0100 bool RServer::internal() const 0101 { 0102 return m_internal; 0103 } 0104 0105 int RServer::threadCount() const 0106 { 0107 return m_threadCount; 0108 } 0109 0110 RServer::ServerState RServer::state() const 0111 { 0112 return m_state; 0113 } 0114 0115 void RServer::setPort(int p) 0116 { 0117 if(p == m_port) 0118 return; 0119 m_port= p; 0120 emit portChanged(); 0121 } 0122 0123 void RServer::incomingConnection(qintptr descriptor) 0124 { 0125 emit eventOccured(QStringLiteral("incoming Connection"), LogController::Debug); 0126 if(!m_corConnection->runAccepter(m_data)) 0127 return; 0128 0129 ServerConnection* connection= new ServerConnection(nullptr, nullptr); 0130 accept(descriptor, connection); 0131 } 0132 0133 void RServer::accept(qintptr descriptor, ServerConnection* connection) 0134 { 0135 if(m_threadPool.isEmpty()) 0136 { 0137 emit eventOccured(QStringLiteral("threadpool is empty - server is stopped"), LogController::Error); 0138 return; 0139 } 0140 0141 auto it= std::min_element( 0142 std::begin(m_threadPool), std::end(m_threadPool), 0143 [](const ThreadInfo& a, const ThreadInfo& b) { return a.m_connectionCount < b.m_connectionCount; }); 0144 0145 if(it == std::end(m_threadPool)) 0146 { 0147 emit eventOccured(QStringLiteral("No thread available - server is stopped"), LogController::Error); 0148 return; 0149 } 0150 0151 it->m_connectionCount++; 0152 connection->moveToThread(it->m_thread); 0153 emit accepting(descriptor, connection); 0154 } 0155 0156 void RServer::setState(const ServerState& state) 0157 { 0158 if(state == m_state) 0159 return; 0160 m_state= state; 0161 emit stateChanged(m_state); 0162 0163 emit eventOccured(QStringLiteral("State Changed to %1").arg(state), LogController::Info); 0164 0165 if(m_state == Error) 0166 emit eventOccured(errorString(), LogController::Error); 0167 } 0168 0169 void RServer::complete() 0170 { 0171 if(!m_connectionThread) 0172 { 0173 emit eventOccured(QStringLiteral("exiting complete there was no thread!"), LogController::Warning); 0174 return; 0175 } 0176 0177 m_connectionsManager.release(); 0178 0179 qDebug() << this << "Quitting thread"; 0180 m_connectionThread->quit(); 0181 m_connectionThread->wait(); 0182 0183 m_connectionThread.release(); 0184 0185 emit eventOccured(QStringLiteral("Rserver Complete"), LogController::Info); 0186 emit completed(); 0187 }