server.cpp (2615B)
1 #include "server.h" 2 3 #include <ptypes/pinet.h> 4 5 #include "bridgeLib/types.h" 6 #include "networkLib/logging.h" 7 8 namespace bridgeServer 9 { 10 Server::Server(int _argc, char** _argv) 11 : m_config(_argc, _argv) 12 , m_plugins(m_config) 13 , m_romPool(m_config) 14 , m_tcpServer([this](std::unique_ptr<networkLib::TcpStream> _stream){onClientConnected(std::move(_stream));} 15 , bridgeLib::g_tcpServerPort) 16 , m_lastDeviceStateUpdate(std::chrono::system_clock::now()) 17 { 18 } 19 20 Server::~Server() 21 { 22 exit(true); 23 m_cvWait.notify_one(); 24 m_clients.clear(); 25 } 26 27 void Server::run() 28 { 29 while(!m_exit) 30 { 31 std::unique_lock lock(m_cvWaitMutex); 32 m_cvWait.wait_for(lock, std::chrono::seconds(10)); 33 34 cleanupClients(); 35 doPeriodicDeviceStateUpdate(); 36 } 37 } 38 39 void Server::onClientConnected(std::unique_ptr<networkLib::TcpStream> _stream) 40 { 41 const auto s = _stream->getPtypesStream(); 42 const std::string name = std::string(ptypes::iptostring(s->get_ip())) + ":" + std::to_string(s->get_port()); 43 44 std::scoped_lock lock(m_mutexClients); 45 m_clients.emplace_back(std::make_unique<ClientConnection>(*this, std::move(_stream), name)); 46 } 47 48 void Server::onClientException(const ClientConnection&, const networkLib::NetException& _e) 49 { 50 m_cvWait.notify_one(); 51 } 52 53 void Server::exit(const bool _exit) 54 { 55 m_exit = _exit; 56 } 57 58 bridgeLib::DeviceState Server::getCachedDeviceState(const bridgeLib::SessionId& _id) 59 { 60 const auto it = m_cachedDeviceStates.find(_id); 61 62 if(it == m_cachedDeviceStates.end()) 63 { 64 static bridgeLib::DeviceState s; 65 return s; 66 } 67 68 auto res = std::move(it->second); 69 m_cachedDeviceStates.erase(it); 70 return res; 71 } 72 73 void Server::cleanupClients() 74 { 75 std::scoped_lock lock(m_mutexClients); 76 77 for(auto it = m_clients.begin(); it != m_clients.end();) 78 { 79 const auto& c = *it; 80 if(!c->isValid()) 81 { 82 const auto& deviceState = c->getDeviceState(); 83 84 if(deviceState.isValid()) 85 m_cachedDeviceStates[c->getPluginDesc().sessionId] = deviceState; 86 87 it = m_clients.erase(it); 88 LOGNET(networkLib::LogLevel::Info, "Client removed, now " << m_clients.size() << " clients left"); 89 } 90 else 91 { 92 ++it; 93 } 94 } 95 } 96 97 void Server::doPeriodicDeviceStateUpdate() 98 { 99 std::scoped_lock lock(m_mutexClients); 100 101 const auto now = std::chrono::system_clock::now(); 102 103 const auto diff = std::chrono::duration_cast<std::chrono::minutes>(now - m_lastDeviceStateUpdate); 104 105 if(diff.count() < static_cast<int>(m_config.deviceStateRefreshMinutes)) 106 return; 107 108 m_lastDeviceStateUpdate = now; 109 110 for (const auto& c : m_clients) 111 c->sendDeviceState(synthLib::StateTypeGlobal); 112 } 113 }