Пример #1
0
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);
			}
		}
	}
}