qi::Future<void> Session_SD::listenStandalone(const qi::Url &address) { if (_init) throw std::runtime_error("Already initialised"); _init = true; _server->addObject(1, _serviceBoundObject); qiLogInfo() << "ServiceDirectory listener created on " << address.str(); qi::Future<void> f = _server->listen(address); std::map<unsigned int, ServiceInfo>::iterator it = _sdObject->connectedServices.find(qi::Message::Service_ServiceDirectory); if (it != _sdObject->connectedServices.end()) { it->second.setEndpoints(_server->endpoints()); return f; } ServiceInfo si; si.setName("ServiceDirectory"); si.setServiceId(qi::Message::Service_ServiceDirectory); si.setMachineId(qi::os::getMachineId()); si.setProcessId(qi::os::getpid()); si.setSessionId("0"); si.setEndpoints(_server->endpoints()); unsigned int regid = _sdObject->registerService(si); (void)regid; _sdObject->serviceReady(qi::Message::Service_ServiceDirectory); //serviceDirectory must have id '1' assert(regid == qi::Message::Service_ServiceDirectory); _server->_server.endpointsChanged.connect(boost::bind(&Session_SD::updateServiceInfo, this)); return f; }
void Session_SD::updateServiceInfo() { ServiceInfo si; si.setName("ServiceDirectory"); si.setServiceId(qi::Message::Service_ServiceDirectory); si.setMachineId(qi::os::getMachineId()); si.setEndpoints(_server->endpoints()); _sdObject->updateServiceInfo(si); }
void TransportSocketCache::insert(const std::string& machineId, const Url& url, MessageSocketPtr socket) { // If a connection is pending for this machine / url, terminate the pendage and set the // service socket as this one boost::mutex::scoped_lock lock(_socketMutex); if (_dying) return; ServiceInfo info; info.setMachineId(machineId); qi::SignalLink disconnectionTracking = socket->disconnected.connect( &TransportSocketCache::onSocketDisconnected, this, url, info) .setCallType(MetaCallType_Direct); ConnectionMap::iterator mIt = _connections.find(machineId); if (mIt != _connections.end()) { std::map<Url, ConnectionAttemptPtr>::iterator uIt = mIt->second.find(url); if (uIt != mIt->second.end()) { auto& connectionAttempt = *uIt->second; QI_ASSERT(!connectionAttempt.endpoint); // If the attempt is done and the endpoint is null, it means the // attempt failed and the promise is set as error. // We replace it by a new one. // If the attempt is not done we do not replace it, otherwise the future // currently in circulation will never finish. if (connectionAttempt.state != State_Pending) connectionAttempt.promise = Promise<MessageSocketPtr>(); connectionAttempt.state = State_Connected; connectionAttempt.endpoint = socket; connectionAttempt.promise.setValue(socket); connectionAttempt.disconnectionTracking = disconnectionTracking; return; } } ConnectionAttemptPtr couple = boost::make_shared<ConnectionAttempt>(); couple->promise = Promise<MessageSocketPtr>(); couple->endpoint = socket; couple->state = State_Connected; couple->relatedUrls.push_back(url); _connections[machineId][url] = couple; couple->promise.setValue(socket); }
qi::Future<void> Session_SD::listenStandalone(const std::vector<qi::Url> &listenAddresses) { if (_init) throw std::runtime_error("Already initialised"); _init = true; _server->addObject(1, _serviceBoundObject); std::ostringstream messInfo; messInfo << "ServiceDirectory listener created on"; qi::FutureBarrier<void> barrier; for (const qi::Url& url : listenAddresses) { messInfo << " " << url.str(); barrier.addFuture(_server->listen(url)); } qiLogInfo() << messInfo.str(); qi::Promise<void> prom; qi::adaptFuture(barrier.future(), prom); qi::Future<void> f = prom.future(); std::map<unsigned int, ServiceInfo>::iterator it = _sdObject->connectedServices.find(qi::Message::Service_ServiceDirectory); if (it != _sdObject->connectedServices.end()) { it->second.setEndpoints(_server->endpoints()); return f; } ServiceInfo si; si.setName("ServiceDirectory"); si.setServiceId(qi::Message::Service_ServiceDirectory); si.setMachineId(qi::os::getMachineId()); si.setProcessId(qi::os::getpid()); si.setSessionId("0"); si.setEndpoints(_server->endpoints()); unsigned int regid = _sdObject->registerService(si); (void)regid; _sdObject->serviceReady(qi::Message::Service_ServiceDirectory); //serviceDirectory must have id '1' QI_ASSERT(regid == qi::Message::Service_ServiceDirectory); _server->_server.endpointsChanged.connect(boost::bind(&Session_SD::updateServiceInfo, this)); return f; }