diff --git a/server/config.cpp b/server/config.cpp index 9863d50a..dd95070a 100644 --- a/server/config.cpp +++ b/server/config.cpp @@ -106,17 +106,25 @@ ClientInfoPtr Config::getClientInfo(const std::string& clientId) const } -ClientInfoPtr Config::addClientInfo(const std::string& clientId) +GroupPtr Config::addClientInfo(ClientInfoPtr client) +{ + GroupPtr group = getGroupFromClient(client); + if (!group) + { + group = std::make_shared(); + group->addClient(client); + groups.push_back(group); + } + return group; +} + + +GroupPtr Config::addClientInfo(const std::string& clientId) { ClientInfoPtr client = getClientInfo(clientId); if (!client) - { client = make_shared(clientId); -//TODO: strange contruct - getGroup(client); - } - - return client; + return addClientInfo(client); } @@ -132,37 +140,28 @@ GroupPtr Config::getGroup(const std::string& groupId) const } -GroupPtr Config::getGroup(ClientInfoPtr client) +GroupPtr Config::getGroupFromClient(const std::string& clientId) { for (auto group: groups) { for (auto c: group->clients) { - if (c->id == client->id) + if (c->id == clientId) return group; } } + return nullptr; +} - GroupPtr group = std::make_shared();//client); - group->clients.push_back(client); - groups.push_back(group); - return group; +GroupPtr Config::getGroupFromClient(ClientInfoPtr client) +{ + return getGroupFromClient(client->id); } json Config::getServerStatus(const json& streams) const { -/* json jClient = json::array(); - if (clientId != "") - { - ClientInfoPtr client = getClientInfo(clientId); - if (client) - jClient += client->toJson(); - } - else - jClient = getClientInfos(); -*/ Host host; host.update(); //TODO: Set MAC and IP @@ -180,14 +179,6 @@ json Config::getServerStatus(const json& streams) const } -/*json Config::getClientInfos() const -{ - json result = json::array(); - for (auto client: clients) - result.push_back(client->toJson()); - return result; -} -*/ json Config::getGroups() const { @@ -200,10 +191,60 @@ json Config::getGroups() const void Config::remove(ClientInfoPtr client) { - auto group = getGroup(client); - auto clients = group->clients; - clients.erase(std::remove(clients.begin(), clients.end(), client), clients.end()); - if (group->clients.empty()) + auto group = getGroupFromClient(client); + if (!group) + return; + group->removeClient(client); + if (group->empty()) + remove(group); +} + + +void Config::remove(GroupPtr group, bool force) +{ + if (!group) + return; + + if (group->empty() || force) groups.erase(std::remove(groups.begin(), groups.end(), group), groups.end()); } +/* +GroupPtr Config::removeFromGroup(const std::string& groupId, const std::string& clientId) +{ + GroupPtr group = getGroup(groupId); + if (!group || (group->id != groupId)) + return group; + + auto client = getClientInfo(clientId); + if (client) + group->clients.erase(std::remove(group->clients.begin(), group->clients.end(), client), group->clients.end()); + + addClientInfo(clientId); + return group; +} + + +GroupPtr Config::setGroupForClient(const std::string& groupId, const std::string& clientId) +{ + GroupPtr oldGroup = getGroupFromClient(clientId); + if (oldGroup && (oldGroup->id == groupId)) + return oldGroup; + + GroupPtr newGroup = getGroup(groupId); + if (!newGroup) + return nullptr; + + auto client = getClientInfo(clientId); + if (!client) + return nullptr; + + if (oldGroup) + removeFromGroup(oldGroup->id, clientId); + + newGroup->addClient(client); + return newGroup; +} +*/ + + diff --git a/server/config.h b/server/config.h index 9e797f7c..856eeb74 100644 --- a/server/config.h +++ b/server/config.h @@ -277,7 +277,7 @@ struct Group ClientInfoPtr client = std::make_shared(); client->fromJson(jClient); client->connected = false; - clients.push_back(client); + addClient(client); } } } @@ -296,6 +296,62 @@ struct Group return j; } + ClientInfoPtr removeClient(const std::string& clientId) + { + for (auto iter = clients.begin(); iter != clients.end(); ++iter) + { + if ((*iter)->id == clientId) + { + clients.erase(iter); + return (*iter); + } + } + return nullptr; + } + + ClientInfoPtr removeClient(ClientInfoPtr client) + { + if (!client) + return nullptr; + + return removeClient(client->id); + } + + ClientInfoPtr getClient(const std::string& clientId) + { + for (auto client: clients) + { + if (client->id == clientId) + return client; + } + return nullptr; + } + + void addClient(ClientInfoPtr client) + { + if (!client) + return; + + for (auto c: clients) + { + if (c->id == client->id) + return; + } + + clients.push_back(client); +/* sort(clients.begin(), clients.end(), + [](const ClientInfoPtr a, const ClientInfoPtr b) -> bool + { + return a.name > b.name; + }); +*/ + } + + bool empty() const + { + return clients.empty(); + } + std::string name; std::string id; std::string streamId; @@ -313,20 +369,24 @@ public: } ClientInfoPtr getClientInfo(const std::string& clientId) const; - ClientInfoPtr addClientInfo(const std::string& clientId); + GroupPtr addClientInfo(const std::string& clientId); + GroupPtr addClientInfo(ClientInfoPtr client); void remove(ClientInfoPtr client); + void remove(GroupPtr group, bool force = false); - GroupPtr getGroup(ClientInfoPtr client); +// GroupPtr removeFromGroup(const std::string& groupId, const std::string& clientId); +// GroupPtr setGroupForClient(const std::string& groupId, const std::string& clientId); + + GroupPtr getGroupFromClient(const std::string& clientId); + GroupPtr getGroupFromClient(ClientInfoPtr client); GroupPtr getGroup(const std::string& groupId) const; -// json getClientInfos() const; json getGroups() const; json getServerStatus(const json& streams) const; void save(); std::vector groups; -// std::vector clients; private: Config(); diff --git a/server/streamServer.cpp b/server/streamServer.cpp index 25f63a50..08e8deec 100644 --- a/server/streamServer.cpp +++ b/server/streamServer.cpp @@ -182,6 +182,49 @@ void StreamServer::onMessageReceived(ControlSession* controlSession, const std:: } } } + else if (request.method == "Group.SetClients") + { + vector clients = request.getParam("clients").get>(); + string groupId = request.getParam("group").get(); + + GroupPtr group = Config::instance().getGroup(groupId); + /// Remove clients from group + for (auto iter = group->clients.begin(); iter != group->clients.end();) + { + auto client = *iter; + if (find(clients.begin(), clients.end(), client->id) != clients.end()) + { + ++iter; + continue; + } + iter = group->clients.erase(iter); + GroupPtr newGroup = Config::instance().addClientInfo(client); + newGroup->streamId = group->streamId; + } + + /// Add clients to group + for (const auto& clientId: clients) + { + ClientInfoPtr client = Config::instance().getClientInfo(clientId); + if (!client) + continue; + GroupPtr oldGroup = Config::instance().getGroupFromClient(client); + if (oldGroup && (oldGroup->id == groupId)) + continue; + + if (oldGroup) + { + oldGroup->removeClient(client); + Config::instance().remove(oldGroup); + } + + group->addClient(client); + } + + if (group->empty()) + Config::instance().remove(group); +// response = Config::instance().getServerStatus(/*clientId,*/ streamManager_->toJson()); + } else if (request.method == "Client.SetLatency") { clientInfo->config.latency = request.getParam("latency", -10000, settings_.bufferMs); @@ -256,8 +299,8 @@ void StreamServer::onMessageReceived(StreamSession* connection, const msg::BaseM logD << "request kServerSettings: " << connection->clientId << "\n"; // std::lock_guard mlock(mutex_); - ClientInfoPtr client = Config::instance().addClientInfo(connection->clientId); - GroupPtr group = Config::instance().getGroup(client); + GroupPtr group = Config::instance().addClientInfo(connection->clientId); + ClientInfoPtr client = group->getClient(connection->clientId); logD << "request kServerSettings\n"; msg::ServerSettings* serverSettings = new msg::ServerSettings();