def topic_connection_handler(self, sock, client_addr, header): """ Process incoming topic connection. Reads in topic name from handshake and creates the appropriate L{TCPROSPub} handler for the connection. @param sock: socket connection @type sock: socket.socket @param client_addr: client address @type client_addr: (str, int) @param header: key/value pairs from handshake header @type header: dict @return: error string or None @rtype: str """ if rospy.core.is_shutdown_requested(): return "Node is shutting down" for required in ['topic', 'md5sum', 'callerid']: if not required in header: return "Missing required '%s' field"%required else: resolved_topic_name = header['topic'] md5sum = header['md5sum'] tm = rospy.impl.registration.get_topic_manager() topic = tm.get_publisher_impl(resolved_topic_name) if not topic: return "[%s] is not a publisher of [%s]. Topics are %s"%(rospy.names.get_caller_id(), resolved_topic_name, tm.get_publications()) elif not topic.data_class or topic.closed: return "Internal error processing topic [%s]"%(resolved_topic_name) elif md5sum != rospy.names.TOPIC_ANYTYPE and md5sum != topic.data_class._md5sum: data_class = topic.data_class actual_type = data_class._type # check to see if subscriber sent 'type' header. If they did, check that # types are same first as this provides a better debugging message if 'type' in header: requested_type = header['type'] if requested_type != actual_type: return "topic types do not match: [%s] vs. [%s]"%(requested_type, actual_type) else: # defaults to actual type requested_type = actual_type return "Client [%s] wants topic [%s] to have datatype/md5sum [%s/%s], but our version has [%s/%s] Dropping connection."%(header['callerid'], resolved_topic_name, requested_type, md5sum, actual_type, data_class._md5sum) else: #TODO:POLLING if polling header is present, have to spin up receive loop as well # #1334: tcp_nodelay support from subscriber option if 'tcp_nodelay' in header: tcp_nodelay = True if header['tcp_nodelay'].strip() == '1' else False else: tcp_nodelay = self.tcp_nodelay_map.get(resolved_topic_name, False) _configure_pub_socket(sock, tcp_nodelay) protocol = TCPROSPub(resolved_topic_name, topic.data_class, is_latch=topic.is_latch, headers=topic.headers) transport = TCPROSTransport(protocol, resolved_topic_name) transport.set_socket(sock, header['callerid']) transport.remote_endpoint = client_addr transport.write_header() topic.add_connection(transport)