void ServiceManager::receive(Message* msg) { RScopeLock lock(_mutex); // is this a response for one of our requests? if (msg->getMeta().find("um.rpc.respId") != msg->getMeta().end()) { std::string respId = msg->getMeta("um.rpc.respId"); if (_findRequests.find(respId) != _findRequests.end()) { // put message into responses and signal waiting thread _findResponses[respId] = new Message(*msg); _findRequests[respId]->signal(); } } // is someone simply asking for a service via find? if (msg->getMeta().find("um.rpc.type") != msg->getMeta().end() && msg->getMeta("um.rpc.type").compare("discover") == 0) { ServiceFilter filter(msg); std::set<ServiceDescription> foundSvcs = findLocal(filter); if (foundSvcs.size() > 0) { ServiceDescription svcDesc = (*(foundSvcs.begin())); Message* foundMsg = svcDesc.toMessage(); foundMsg->setReceiver(msg->getMeta("um.rpc.mgrId")); foundMsg->putMeta("um.rpc.respId", msg->getMeta("um.rpc.reqId")); foundMsg->putMeta("um.rpc.mgrId", _svcSub->getUUID()); // if (_svcPub->isPublishingTo(msg->getMeta("um.rpc.mgrId"))) { _svcPub->send(foundMsg); // } else { // // queue message and send in welcome // _pendingMessages[msg->getMeta("um.rpc.mgrId")].push_back(std::make_pair(Thread::getTimeStampMs(), foundMsg)); // } delete foundMsg; } } // is this the start of a continuous query? if (msg->getMeta().find("um.rpc.type") != msg->getMeta().end() && msg->getMeta("um.rpc.type").compare("startDiscovery") == 0) { ServiceFilter filter(msg); _remoteQueries[filter.getUUID()] = filter; UM_LOG_INFO("Received query for '%s'", filter._svcName.c_str()); // do we have such a service? std::set<ServiceDescription> foundSvcs = findLocal(filter); std::set<ServiceDescription>::iterator svcDescIter = foundSvcs.begin(); while(svcDescIter != foundSvcs.end()) { Message* foundMsg = svcDescIter->toMessage(); foundMsg->setReceiver(msg->getMeta("um.rpc.mgrId")); foundMsg->putMeta("um.rpc.filterId", filter.getUUID()); foundMsg->putMeta("um.rpc.type", "discovered"); foundMsg->putMeta("um.rpc.mgrId", _svcSub->getUUID()); _svcPub->send(foundMsg); delete foundMsg; svcDescIter++; } } // is this the end of a continuous query? if (msg->getMeta().find("um.rpc.type") != msg->getMeta().end() && msg->getMeta("um.rpc.type").compare("stopDiscovery") == 0) { ServiceFilter filter(msg); if (_remoteQueries.find(filter.getUUID()) != _remoteQueries.end()) { _remoteQueries.erase(filter.getUUID()); } } // is this a reply to a continuous service query? if (msg->getMeta().find("um.rpc.type") != msg->getMeta().end() && (msg->getMeta("um.rpc.type").compare("discovered") == 0 || msg->getMeta("um.rpc.type").compare("vanished") == 0)) { // _svcQueries comparator uses filter uuid ServiceFilter keyFilter(""); keyFilter._uuid = msg->getMeta("um.rpc.filterId"); if (_localQueries.find(keyFilter) != _localQueries.end()) { ResultSet<ServiceDescription>* listener = _localQueries[keyFilter]; assert(msg->getMeta("um.rpc.desc.channel").size() > 0); assert(msg->getMeta("um.rpc.mgrId").size() > 0); std::string svcChannel = msg->getMeta("um.rpc.desc.channel"); std::string managerId = msg->getMeta("um.rpc.mgrId"); if (_remoteSvcDesc.find(managerId) == _remoteSvcDesc.end() || _remoteSvcDesc[managerId].find(svcChannel) == _remoteSvcDesc[managerId].end()) { _remoteSvcDesc[managerId][svcChannel] = ServiceDescription(msg); _remoteSvcDesc[managerId][svcChannel]._svcManager = this; } assert(_remoteSvcDesc.find(managerId) != _remoteSvcDesc.end()); assert(_remoteSvcDesc[managerId].find(svcChannel) != _remoteSvcDesc[managerId].end()); if (msg->getMeta("um.rpc.type").compare("discovered") == 0) { listener->add(_remoteSvcDesc[managerId][svcChannel], toStr(this)); } else { listener->remove(_remoteSvcDesc[managerId][svcChannel], toStr(this)); _remoteSvcDesc[managerId].erase(svcChannel); } } } }