void RTPPublisher::removed(const SubscriberStub& sub, const NodeStub& node) { RScopeLock lock(_mutex); int status; std::string ip = sub.getIP(); uint16_t port = sub.getPort(); if (!ip.length()) //only use separate subscriber ip (for multicast support etc.), if specified ip = node.getIP(); // do we now about this sub via this node? bool subscriptionFound = false; std::pair<_domainSubs_t::iterator, _domainSubs_t::iterator> subIter = _domainSubs.equal_range(sub.getUUID()); while(subIter.first != subIter.second) { if (subIter.first->second.first.getUUID() == node.getUUID()) { subscriptionFound = true; break; } subIter.first++; } if (!subscriptionFound) return; UM_LOG_INFO("%s: lost a %s subscriber (%s:%u) for channel %s", SHORT_UUID(_uuid).c_str(), sub.isMulticast() ? "multicast" : "unicast", ip.c_str(), port, _channelName.c_str()); struct libre::sa addr; libre::sa_init(&addr, AF_INET); if ((status = libre::sa_set_str(&addr, ip.c_str(), port))) UM_LOG_WARN("%s: error %d in libre::sa_set_str(%s:%u): %s", SHORT_UUID(_uuid).c_str(), status, ip.c_str(), port, strerror(status)); else _destinations.erase(ip+":"+toStr(port)); if (_domainSubs.count(sub.getUUID()) == 1) { // about to vanish if (_greeter != NULL) { Publisher pub(Publisher(StaticPtrCast<PublisherImpl>(shared_from_this()))); _greeter->farewell(pub, sub); } _subs.erase(sub.getUUID()); } _domainSubs.erase(subIter.first); UMUNDO_SIGNAL(_pubLock); }
void RTPPublisher::added(const SubscriberStub& sub, const NodeStub& node) { RScopeLock lock(_mutex); int status; std::string ip = sub.getIP(); uint16_t port = sub.getPort(); if (!ip.length()) //only use separate subscriber ip (for multicast support etc.), if specified ip = node.getIP(); // do we already now about this sub via this node? std::pair<_domainSubs_t::iterator, _domainSubs_t::iterator> subIter = _domainSubs.equal_range(sub.getUUID()); while(subIter.first != subIter.second) { if (subIter.first->second.first.getUUID() == node.getUUID()) return; // we already know about this sub from this node subIter.first++; } UM_LOG_INFO("%s: received a new %s subscriber (%s:%u) for channel %s", SHORT_UUID(_uuid).c_str(), sub.isMulticast() ? "multicast" : "unicast", ip.c_str(), port, _channelName.c_str()); struct libre::sa addr; libre::sa_init(&addr, AF_INET); status = libre::sa_set_str(&addr, ip.c_str(), port); if (status) { UM_LOG_WARN("%s: error %d in libre::sa_set_str(%s:%u): %s", SHORT_UUID(_uuid).c_str(), status, ip.c_str(), port, strerror(status)); } else { _destinations[ip + ":" + toStr(port)] = addr; } _subs[sub.getUUID()] = sub; _domainSubs.insert(std::make_pair(sub.getUUID(), std::make_pair(node, sub))); if (_greeter != NULL && _domainSubs.count(sub.getUUID()) == 1) { // only perform greeting for first occurence of subscriber Publisher pub(StaticPtrCast<PublisherImpl>(shared_from_this())); _greeter->welcome(pub, sub); } UMUNDO_SIGNAL(_pubLock); }
/** * Another ServiceManager was added. * * Send all local continuous queries. */ void ServiceManager::welcome(Publisher& pub, const SubscriberStub& subStub) { RScopeLock lock(_mutex); UM_LOG_INFO("found remote ServiceManager - sending %d queries", _localQueries.size()); std::map<ServiceFilter, ResultSet<ServiceDescription>*>::iterator queryIter = _localQueries.begin(); while (queryIter != _localQueries.end()) { Message* queryMsg = queryIter->first.toMessage(); queryMsg->putMeta("um.rpc.type", "startDiscovery"); queryMsg->putMeta("um.sub", subStub.getUUID()); queryMsg->putMeta("um.rpc.mgrId", _svcSub->getUUID()); _svcPub->send(queryMsg); delete queryMsg; queryIter++; } if (_pendingMessages.find(subStub.getUUID()) != _pendingMessages.end()) { std::list<std::pair<uint64_t, Message*> >::iterator msgIter = _pendingMessages[subStub.getUUID()].begin(); while(msgIter != _pendingMessages[subStub.getUUID()].end()) { _svcPub->send(msgIter->second); delete msgIter->second; } _pendingMessages.erase(subStub.getUUID()); } }
/** * A ServiceManager was removed. */ void ServiceManager::farewell(Publisher& pub, const SubscriberStub& subStub) { RScopeLock lock(_mutex); UM_LOG_INFO("removed remote ServiceManager - notifying", _localQueries.size()); // did this publisher responded to our queries before? if (_remoteSvcDesc.find(subStub.getUUID()) != _remoteSvcDesc.end()) { // check all local queries if the remote services matched and notify about removal std::map<ServiceFilter, ResultSet<ServiceDescription>*>::iterator queryIter = _localQueries.begin(); while(queryIter != _localQueries.end()) { std::map<std::string, ServiceDescription>::iterator remoteSvcIter = _remoteSvcDesc[subStub.getUUID()].begin(); while(remoteSvcIter != _remoteSvcDesc[subStub.getUUID()].end()) { if (queryIter->first.matches(remoteSvcIter->second)) { queryIter->second->removed(remoteSvcIter->second); } remoteSvcIter++; } queryIter++; } } _remoteSvcDesc.erase(subStub.getUUID()); }