def get_service_headers(service_name, service_uri): """ Utility for connecting to a service and retrieving the TCPROS headers. Services currently do not declare their type with the master, so instead we probe the service for its headers. @param service_name: name of service @type service_name: str @param service_uri: ROSRPC URI of service @type service_uri: str @return: map of header fields @rtype: dict @raise ROSServiceException: if service has invalid information @raise ROSServiceIOException: if unable to communicate with service """ try: dest_addr, dest_port = rospy.parse_rosrpc_uri(service_uri) except: raise ROSServiceException("service [%s] has an invalid RPC URI [%s]"%(service_name, service_uri)) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: try: # connect to service and probe it to get the headers s.settimeout(5.0) s.connect((dest_addr, dest_port)) header = { 'probe':'1', 'md5sum':'*', 'callerid':'/rosservice', 'service':service_name} rosgraph.network.write_ros_handshake_header(s, header) return rosgraph.network.read_ros_handshake_header(s, StringIO(), 2048) except socket.error: raise ROSServiceIOException("Unable to communicate with service [%s], address [%s]"%(service_name, service_uri)) finally: if s is not None: s.close()
def get_service_class(service_name): master = roslib.scriptutil.get_master() code, msg, service_uri = master.lookupService(CALLER_ID, service_name) dest_addr, dest_port = rospy.parse_rosrpc_uri(service_uri) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: try: # connect to service and probe it to get the headers s.settimeout(5.0) s.connect((dest_addr, dest_port)) header = { 'probe': '1', 'md5sum': '*', 'callerid': '/rosservice', 'service': service_name } roslib.network.write_ros_handshake_header(s, header) return roslib.network.read_ros_handshake_header( s, cStringIO.StringIO(), 2048).get('type', None) except socket.error: raise ROSServiceIOException( "Unable to communicate with service [%s], address [%s]" % (service_name, service_uri)) finally: if s is not None: s.close()
def _getServiceInfo(self, services): ''' Gets service info through the RPC interface of the service. This method blocks until the info is retrieved or socket timeout is reached (0.5 seconds). :param service: the name of the service :type service: str :param uri: the uri of the service :type uri: str ''' for (service, uri) in services.items(): with self._lock: if service in self.__cached_services: if time.time() - self.__cached_services[service][2] < self.MAX_PING_SEC: return if uri is not None: dest_addr = dest_port = None try: dest_addr, dest_port = rospy.parse_rosrpc_uri(uri) except: continue # raise ROSServiceException("service [%s] has an invalid RPC URI [%s]"%(service, uri)) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: # connect to service and probe it to get the headers s.settimeout(0.5) s.connect((dest_addr, dest_port)) header = {'probe': '1', 'md5sum': '*', 'callerid': self.ros_node_name, 'service': service} roslib.network.write_ros_handshake_header(s, header) buf = io.StringIO() if sys.version_info < (3, 0) else io.BytesIO() stype = roslib.network.read_ros_handshake_header(s, buf, 2048) with self._lock: self.__new_master_state.getService(service).type = stype['type'] self.__cached_services[service] = (uri, stype['type'], time.time()) except socket.error: with self._lock: try: del self.__cached_services[service] except: pass # raise ROSServiceIOException("Unable to communicate with service [%s], address [%s]"%(service, uri)) except: with self._lock: self._limited_log(service, "can't get service type: %s" % traceback.format_exc(), level=rospy.DEBUG) with self._lock: try: del self.__cached_services[service] except: pass pass finally: if s is not None: s.close()
def _getServiceInfo(self, services): ''' Gets service info through the RPC interface of the service. This method blocks until the info is retrieved or socket timeout is reached (0.5 seconds). :param service: the name of the service :type service: str :param uri: the uri of the service :type uri: str ''' for (service, uri) in services.items(): with self._lock: if service in self.__cached_services: if time.time() - self.__cached_services[service][2] < self.MAX_PING_SEC: return if uri is not None: dest_addr = dest_port = None try: dest_addr, dest_port = rospy.parse_rosrpc_uri(uri) except: continue # raise ROSServiceException("service [%s] has an invalid RPC URI [%s]"%(service, uri)) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: # connect to service and probe it to get the headers s.settimeout(0.5) s.connect((dest_addr, dest_port)) header = {'probe': '1', 'md5sum': '*', 'callerid': self.ros_node_name, 'service': service} roslib.network.write_ros_handshake_header(s, header) stype = roslib.network.read_ros_handshake_header(s, cStringIO.StringIO(), 2048) with self._lock: self.__new_master_state.getService(service).type = stype['type'] self.__cached_services[service] = (uri, stype['type'], time.time()) except socket.error: with self._lock: try: del self.__cached_services[service] except: pass # raise ROSServiceIOException("Unable to communicate with service [%s], address [%s]"%(service, uri)) except: with self._lock: self._limited_log(service, "can't get service type: %s" % traceback.format_exc(), level=rospy.DEBUG) with self._lock: try: del self.__cached_services[service] except: pass pass finally: if s is not None: s.close()
def getServiceInfo(self, services): ''' Gets service info through the RPC interface of the service. @param service: the name of the service @type service: C{str} @param uri: the uri of the service @type uri: C{str} ''' for (service, uri) in services.items(): if not uri is None: type = dest_addr = dest_port = None try: dest_addr, dest_port = rospy.parse_rosrpc_uri(uri) except: # print "ERROR while get service info" continue # return # raise ROSServiceException("service [%s] has an invalid RPC URI [%s]"%(service, uri)) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: # connect to service and probe it to get the headers s.settimeout(0.5) s.connect((dest_addr, dest_port)) header = { 'probe': '1', 'md5sum': '*', 'callerid': rospy.get_name(), 'service': service } roslib.network.write_ros_handshake_header(s, header) type = roslib.network.read_ros_handshake_header( s, cStringIO.StringIO(), 2048) except socket.error: pass # raise ROSServiceIOException("Unable to communicate with service [%s], address [%s]"%(service, uri)) except: pass finally: if s is not None: s.close() self._lock.acquire(True) try: self.new_master_state.getService(service).type = type['type'] except: pass # print "ignored:" # import traceback # traceback.print_exc() # print "type field in service header not available, type:", type self._lock.release()
def getServiceInfo(self, services): ''' Gets service info through the RPC interface of the service. @param service: the name of the service @type service: C{str} @param uri: the uri of the service @type uri: C{str} ''' for (service, uri) in services.items(): if not uri is None: type = dest_addr = dest_port = None try: dest_addr, dest_port = rospy.parse_rosrpc_uri(uri) except: # print "ERROR while get service info" continue # return # raise ROSServiceException("service [%s] has an invalid RPC URI [%s]"%(service, uri)) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: # connect to service and probe it to get the headers s.settimeout(0.5) s.connect((dest_addr, dest_port)) header = { 'probe':'1', 'md5sum':'*', 'callerid':rospy.get_name(), 'service':service} roslib.network.write_ros_handshake_header(s, header) type = roslib.network.read_ros_handshake_header(s, cStringIO.StringIO(), 2048) except socket.error: pass # raise ROSServiceIOException("Unable to communicate with service [%s], address [%s]"%(service, uri)) except: pass finally: if s is not None: s.close() self._lock.acquire(True) try: self.new_master_state.getService(service).type = type['type'] except: pass # print "ignored:" # import traceback # traceback.print_exc() # print "type field in service header not available, type:", type self._lock.release()
def get_service_headers(service_name, service_uri): """ Utility for connecting to a service and retrieving the TCPROS headers. Services currently do not declare their type with the master, so instead we probe the service for its headers. @param service_name: name of service @type service_name: str @param service_uri: ROSRPC URI of service @type service_uri: str @return: map of header fields @rtype: dict @raise ROSServiceException: if service has invalid information @raise ROSServiceIOException: if unable to communicate with service """ try: dest_addr, dest_port = rospy.parse_rosrpc_uri(service_uri) except: raise ROSServiceException("service [%s] has an invalid RPC URI [%s]" % (service_name, service_uri)) if rosgraph.network.use_ipv6(): s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) else: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: try: # connect to service and probe it to get the headers s.settimeout(5.0) s.connect((dest_addr, dest_port)) header = { 'probe': '1', 'md5sum': '*', 'callerid': '/rosservice', 'service': service_name } rosgraph.network.write_ros_handshake_header(s, header) return rosgraph.network.read_ros_handshake_header( s, StringIO(), 2048) except socket.error: raise ROSServiceIOException( "Unable to communicate with service [%s], address [%s]" % (service_name, service_uri)) finally: if s is not None: s.close()
def test_parse_rosrpc_uri(self): from rospy.core import parse_rosrpc_uri valid = [('rosrpc://localhost:1234/', 'localhost', 1234), ('rosrpc://localhost2:1234', 'localhost2', 1234), ('rosrpc://third:1234/path/bar', 'third', 1234), ('rosrpc://foo.com:1/', 'foo.com', 1), ('rosrpc://foo.com:1/', 'foo.com', 1)] for t, addr, port in valid: paddr, pport = rospy.core.parse_rosrpc_uri(t) self.assertEquals(addr, paddr) self.assertEquals(port, pport) # validate that it's a top-level API method self.assertEquals(rospy.core.parse_rosrpc_uri(t), rospy.parse_rosrpc_uri(t)) invalid = ['rosrpc://:1234/', 'rosrpc://localhost', 'http://localhost:1234/'] for i in invalid: try: parse_rosrpc_uri(i) self.fail("%s was an invalid rosrpc uri"%i) except: pass
def getServiceType(serviceName, serviceUri): dest_addr, dest_port = rospy.parse_rosrpc_uri(serviceUri) if rosgraph.network.use_ipv6(): s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) else: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: s.settimeout(5.0) s.connect((dest_addr, dest_port)) header = { 'probe': '1', 'md5sum': '*', 'callerid': '/rosservice', 'service': serviceName } rosgraph.network.write_ros_handshake_header(s, header) return rosgraph.network.read_ros_handshake_header(s, StringIO(), 2048).get( 'type', None) finally: if s is not None: s.close()
def get_service_class(self, allow_get_type=False): ''' Get the service class using the type of the service. NOTE: this method is from `rosservice` and changed to avoid a probe call to the service. :param allow_get_type: allow to connect to service and get the type if the type is not valid (in case of other host) :type allow_get_type: bool :return: service class :rtype: ServiceDefinition: service class :raise: ``ROSServiceException``, if service class cannot be retrieved ''' if not self.__service_class is None: return self.__service_class type = self.type # request the type if it is empty and allowed if not type and allow_get_type and self.uri: dest_addr = dest_port = None try: dest_addr, dest_port = rospy.parse_rosrpc_uri(self.uri) except: pass else: import socket import cStringIO s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: # connect to service and probe it to get the headers s.settimeout(0.5) s.connect((dest_addr, dest_port)) header = { 'probe':'1', 'md5sum':'*', 'callerid':rospy.get_name(), 'service':self.name} roslib.network.write_ros_handshake_header(s, header) type = roslib.network.read_ros_handshake_header(s, cStringIO.StringIO(), 2048) type = type['type'] except socket.error: pass except: pass finally: if s is not None: s.close() import rosservice if not type: raise rosservice.ROSServiceException("Not valid type of service [%s]."%str(type)) # get the Service class so we can populate the request service_class = roslib.message.get_service_class(type) # #1083: roscpp services are currently returning the wrong type if service_class and self.type.endswith('Request') and \ not hasattr(service_class, "_request_class"): type = type[:-7] service_class = roslib.message.get_service_class(type) if service_class is None: pkg = roslib.names.resource_name_package(self.type) raise rosservice.ROSServiceException("Unable to load type [%s].\n"%self.type+ "Have you typed 'make' in [%s]?"%pkg) self.__service_class = service_class return service_class
def get_service_class(self, allow_get_type=False): ''' Get the service class using the type of the service. NOTE: this method is from `rosservice` and changed to avoid a probe call to the service. :param allow_get_type: allow to connect to service and get the type if the type is not valid (in case of other host) :type allow_get_type: bool :return: service class :rtype: ServiceDefinition: service class :raise: ``ROSServiceException``, if service class cannot be retrieved ''' if self.__service_class is not None: return self.__service_class srv_type = self.type # request the type if it is empty and allowed if not srv_type and allow_get_type and self.uri: dest_addr = dest_port = None try: dest_addr, dest_port = rospy.parse_rosrpc_uri(self.uri) except: pass else: import socket import cStringIO s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: # connect to service and probe it to get the headers s.settimeout(0.5) s.connect((dest_addr, dest_port)) header = { 'probe': '1', 'md5sum': '*', 'callerid': rospy.get_name(), 'service': self.name } roslib.network.write_ros_handshake_header(s, header) srv_type = roslib.network.read_ros_handshake_header( s, cStringIO.StringIO(), 2048) srv_type = srv_type['type'] except socket.error: pass except: pass finally: if s is not None: s.close() import rosservice if not srv_type: raise rosservice.ROSServiceException( "Not valid type of service [%s]." % str(srv_type)) # get the Service class so we can populate the request service_class = roslib.message.get_service_class(srv_type) # #1083: roscpp services are currently returning the wrong type if service_class and self.type.endswith('Request') and \ not hasattr(service_class, "_request_class"): srv_type = srv_type[:-7] service_class = roslib.message.get_service_class(srv_type) if service_class is None: pkg = roslib.names.resource_name_package(self.type) raise rosservice.ROSServiceException( "Unable to load type [%s].\n" % self.type + "Have you typed 'make' in [%s]?" % pkg) self.__service_class = service_class return service_class
def _getServiceInfo(self, services): ''' Gets service info through the RPC interface of the service. This method blocks until the info is retrieved or socket timeout is reached (0.5 seconds). :param service: the name of the service :type service: str :param uri: the uri of the service :type uri: str ''' for (service, uri) in services.items(): with self._lock: if self.__cached_services.has_key(service): if time.time( ) - self.__cached_services[service][2] < self.MAX_PING_SEC: return if not uri is None: type = dest_addr = dest_port = None try: dest_addr, dest_port = rospy.parse_rosrpc_uri(uri) except: # print "ERROR while get service info" continue # return # raise ROSServiceException("service [%s] has an invalid RPC URI [%s]"%(service, uri)) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: # connect to service and probe it to get the headers s.settimeout(0.5) s.connect((dest_addr, dest_port)) header = { 'probe': '1', 'md5sum': '*', 'callerid': self.ros_node_name, 'service': service } roslib.network.write_ros_handshake_header(s, header) stype = roslib.network.read_ros_handshake_header( s, cStringIO.StringIO(), 2048) # print "_getServiceInfo _lock try..", threading.current_thread() with self._lock: # print "get info about service", service, uri self.__new_master_state.getService( service).type = stype['type'] self.__cached_services[service] = (uri, stype['type'], time.time()) # print "_getServiceInfo _lock RET", threading.current_thread() except socket.error: # print "_getServiceInfo _lock try..", threading.current_thread() with self._lock: try: # print "delete socket service", service, uri del self.__cached_services[service] except: pass # raise ROSServiceIOException("Unable to communicate with service [%s], address [%s]"%(service, uri)) # print "_getServiceInfo _lock RET", threading.current_thread() except: import traceback with self._lock: self._limited_log( service, "can't get service type: %s" % traceback.format_exc()) # print traceback.format_exc() # print "_getServiceInfo _lock try..", threading.current_thread() with self._lock: try: # print "delete service", service, uri del self.__cached_services[service] except: pass # print "_getServiceInfo _lock RET", threading.current_thread() pass finally: if s is not None: s.close()
def _getServiceInfo(self, services): ''' Gets service info through the RPC interface of the service. This method blocks until the info is retrieved or socket timeout is reached (0.5 seconds). :param service: the name of the service :type service: str :param uri: the uri of the service :type uri: str ''' for (service, uri) in services.items(): with self._lock: if self.__cached_services.has_key(service): if time.time() - self.__cached_services[service][2] < self.MAX_PING_SEC: return if not uri is None: type = dest_addr = dest_port = None try: dest_addr, dest_port = rospy.parse_rosrpc_uri(uri) except: # print "ERROR while get service info" continue # return # raise ROSServiceException("service [%s] has an invalid RPC URI [%s]"%(service, uri)) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: # connect to service and probe it to get the headers s.settimeout(0.5) s.connect((dest_addr, dest_port)) header = { 'probe':'1', 'md5sum':'*', 'callerid':self.ros_node_name, 'service':service} roslib.network.write_ros_handshake_header(s, header) type = roslib.network.read_ros_handshake_header(s, cStringIO.StringIO(), 2048) # print "_getServiceInfo _lock try..", threading.current_thread() with self._lock: # print "get info about service", service, uri self.__new_master_state.getService(service).type = type['type'] self.__cached_services[service] = (uri, type['type'], time.time()) # print "_getServiceInfo _lock RET", threading.current_thread() except socket.error: # print "_getServiceInfo _lock try..", threading.current_thread() with self._lock: try: # print "delete socket service", service, uri del self.__cached_services[service] except: pass # raise ROSServiceIOException("Unable to communicate with service [%s], address [%s]"%(service, uri)) # print "_getServiceInfo _lock RET", threading.current_thread() except: # import traceback # print traceback.format_exc() # print "_getServiceInfo _lock try..", threading.current_thread() with self._lock: try: # print "delete service", service, uri del self.__cached_services[service] except: pass # print "_getServiceInfo _lock RET", threading.current_thread() pass finally: if s is not None: s.close()