#include "dispatcherserver.h" DispatcherServer::DispatcherServer(PIEthernet::Address addr) : eth(PIEthernet::TCP_Server) { client_gid = 0; eth.setParameter(PIEthernet::ReuseAddress); CONNECTU(ð, newConnection, this, newConnection); eth.listen(addr, true); piCoutObj << "server started" << addr; CONNECTU(&status_timer, tickEvent, this, printStatus); CONNECTU(&timeout_timer, tickEvent, this, cleanClients); status_timer.start(1000); timeout_timer.start(5000); } DispatcherServer::~DispatcherServer() { eth.close(); piCoutObj << "server stoped"; } void DispatcherServer::cleanClients() { PIVector rm; map_mutex.lock(); for (auto c: clients) { if (!index_c_servers.contains(c) && !index_c_clients.contains(c)) { if (rm_clients.contains(c)) rm << c; else rm_clients << c; } else rm_clients.removeAll(c); } for (auto c: rm_clients) { if (clients.contains(c)) rm << c; } map_mutex.unlock(); for (auto c: rm) { c->close(); // c->deleteLater(); } } void DispatcherServer::printStatus() { map_mutex.lock(); piCout << PICoutManipulators::NewLine; piCout << "Connections:"; for (auto c: clients) { piCout << " " << c->address(); } piCout << "Servers:"; auto it = c_servers.makeIterator(); while(it.next()){ piCout << " " << it.key(); it.value()->printStatus(); } map_mutex.unlock(); } void DispatcherServer::disconnectClient(DispatcherClient *client) { if (!clients.contains(client)) { piCoutObj << "INVALID client" << client; return; } piCoutObj << "remove client" << client; map_mutex.lock(); clients.removeOne(client); CloudServer * cs = index_c_servers.value(client, nullptr); if (cs) { PIVector cscv = cs->getClients(); for(auto csc : cscv) { csc->close(); clients.removeOne(csc); index_c_clients.removeOne(csc); csc->deleteLater(); } c_servers.remove(cs->serverName()); index_c_servers.removeOne(client); } CloudServer * cc = index_c_clients.value(client, nullptr); if (cc) { cc->removeClient(client); index_c_clients.removeOne(client); } client->close(); map_mutex.unlock(); client->deleteLater(); } void DispatcherServer::newConnection(PIEthernet *cl) { DispatcherClient * client = new DispatcherClient(cl, client_gid++); CONNECTU(client, disconnectEvent, this, disconnectClient); CONNECTL(client, registerServer, [this](PIString sname, DispatcherClient * c){ map_mutex.lock(); piCoutObj << "add new Server ->" << sname; CloudServer * cs = new CloudServer(c, sname); c_servers.insert(sname, cs); index_c_servers.insert(c, cs); map_mutex.unlock(); }); CONNECTL(client, registerClient, [this](PIString sname, DispatcherClient * c){ map_mutex.lock(); CloudServer * cs = c_servers.value(sname, nullptr); if (cs) { piCoutObj << "add new Client to Server ->" << sname; cs->addClient(c); index_c_clients.insert(c, cs); } else { rm_clients << c; } map_mutex.unlock(); }); piCoutObj << "add client" << client; client->start(); map_mutex.lock(); clients.push_back(client); map_mutex.unlock(); }