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; }
//we ensure in that function that connect to all events are already setup when we said we are connect. //that way we can't be connected without being fully ready. qi::FutureSync<void> ServiceDirectoryClient::connect(const qi::Url &serviceDirectoryURL) { if (isConnected()) { const char* s = "Session is already connected"; qiLogInfo() << s; return qi::makeFutureError<void>(s); } _sdSocket = qi::makeTransportSocket(serviceDirectoryURL.protocol()); if (!_sdSocket) return qi::makeFutureError<void>(std::string("unrecognized protocol '") + serviceDirectoryURL.protocol() + "' in url '" + serviceDirectoryURL.str() + "'"); _sdSocketDisconnectedSignalLink = _sdSocket->disconnected.connect(&ServiceDirectoryClient::onSocketDisconnected, this, _1); _remoteObject.setTransportSocket(_sdSocket); qi::Promise<void> promise; qi::Future<void> fut = _sdSocket->connect(serviceDirectoryURL); fut.connect(&ServiceDirectoryClient::onSocketConnected, this, _1, promise); return promise.future(); }
qi::Future<void> TransportServer::listen(const qi::Url &url, qi::EventLoop* ctx) { TransportServerImplPtr impl; if (url.protocol() == "tcp" || url.protocol() == "tcps") { impl = TransportServerAsioPrivate::make(this, ctx); } else { const char* s = "Unrecognized protocol to create the TransportServer."; qiLogError() << s; return qi::makeFutureError<void>(s); } { boost::mutex::scoped_lock l(_implMutex); _impl.push_back(impl); } return impl->listen(url); }
int main_server() { qi::Session sd; if (sd.listenStandalone(serverUrl).hasError()) { std::cerr << "Service directory can't listen on " << serverUrl.str() << "." << std::endl; return 1; } serverUrl = sd.endpoints()[0]; std::cout << "Service Directory ready on " << serverUrl.str() << std::endl; qi::Session session; qi::AnyObject obj = make_service(); session.connect(sd.endpoints()[0]); qi::Url sessionUrl("tcp://0.0.0.0:0"); session.listen(sessionUrl); session.registerService("serviceTest", obj); std::cout << "serviceTest ready." << std::endl; serverReady = true; while (!clientDone) qi::os::sleep(60); return 0; }
int main_gateway(const qi::Url& serverUrl) { qi::Gateway gate; gate.attachToServiceDirectory(serverUrl); gateUrl = "tcp://0.0.0.0:0"; gate.listen(gateUrl); gateUrl = gate.endpoints()[0]; std::cout << "Gateway listening on " << gateUrl.str() << std::endl; while (!clientDone) qi::os::sleep(60); return 0; }
void SessionPrivate::addSdSocketToCache(Future<void> f, const qi::Url& url, qi::Promise<void> p) { qiLogDebug() << "addSocketToCache processing"; if (f.hasError()) { qiLogDebug() << "addSdSocketToCache: connect reported failure"; _serviceHandler.removeService("ServiceDirectory"); p.setError(f.error()); return; } // Allow the SD process to use the existing socket to talk to our services _serverObject.registerSocket(_sdClient.socket()); /* Allow reusing the SD socket for communicating with services. * To do this, we must add it to our socket cache, and for this we need * to know the sd machineId */ std::string mid; try { mid = _sdClient.machineId(); } catch (const std::exception& e) { // Provide a nice message for backward compatibility qiLogVerbose() << e.what(); qiLogWarning() << "Failed to obtain machineId, connection to service directory will not be reused for other services."; p.setValue(0); return; } TransportSocketPtr s = _sdClient.socket(); qiLogVerbose() << "Inserting sd to cache for " << mid <<" " << url.str() << std::endl; _socketsCache.insert(mid, s->remoteEndpoint(), s); p.setValue(0); }
qi::FutureSync<void> Session::listen(const qi::Url &address) { qiLogInfo() << "Session listener created on " << address.str(); return _p->_serverObject.listen(address); }