XMLRPC服务器如何启动

2023-09-14  

core调用了roslaunch.main,我们继续追踪,进到ros_comm-noet-develtoolsroslaunchsrcroslaunch文件夹中,发现有个__init__.py文件,说明这个文件夹是一个包,打开__init__.py文件找到def main(argv=sys.argv),这就是roscore调用的函数roslaunch.main的实现,如下(这里只保留主要的代码,不太重要的删掉了)。

def main(argv=sys.argv):
    opons = None
    logger = None
    try:
        from . import rlutil
        paer = _get_optparse()
        
        (options, args) = parser.parse_args(argv[1:])
        args = rlutil.resolve_launch_arguments(args)
        wri_d_file(options.pid_fn, options.ce, options.port)
        uuid = rlutil.get_or_generate_uuid(options.run_id, options.wt_for_master)
        configure_logging(uuid)
        # #3088: don't check disk usage on remote machines
        if not options.child_name and not options.skip_log_check:
            rlutil.check_log_disk_usage()


        logger = logging.getLogger('roslaunch')
        logger.info("roslaunch starting with args %s"%str(argv))
        logger.info("roslaunch env is %s"%os.environ)
            
        if options.child_name:
           # 这里没执行到,就不列出来了
        else:
            logger.info('starting in server mode')
            # #1491 change terminal name
            if not options.disable_title:
                rlutil.change_terminal_name(args, options.core)
            # Re roslaunch string from stdin when - is passed as launch filename.
            roslaunch_strs = []
            # This is a roslaunch parent, spin up parent server and launch processes.
            # args are the roslaunch files to load
            from . import parent as roslaunch_parent
            # force a port binding spec if we are running a core
            if options.core:
                options.port = options.port or DEFAULT_MASTER_PORT
            p = roslaunch_parent.ROSLaunchParent(uuid, args, roslaunch_strs=roslaunch_strs, is_core=options.core, port=options.port, local_only=options.local_only, verbose=options.verbose,  force_screen=options.force_screen, force_log=options.force_log, num_workers=options.num_workers, timeout=options.timeout, master_logger_level=options.master_logger_level, show_summary=not options.no_summary, force_required=options.force_required, sigint_timeout=options.sigint_timeout, sigterm_timeout=options.sigterm_timeout)
            p.start()
            p.spin()

roslaunch.main开启了日志,日志记录的信息可以帮我们了解main函数执行的顺序。

我们去Ubuntu的.ros/log/路径下,打开roslaunch-ubuntu-52246.log日志文件,内容如下。

通过阅读日志我们发现,main函数首先检查日志文件夹磁盘占用情况,如果有剩余空间就继续往下运行。

然后把运行roscore的终端的标题给改了。

再调用ROSLaunchParent类中的函数,这大概就是main函数中最重要的地方了。

ROSLaunchParent类的定义是在同一路径下的parent.py文件中。为什么叫LaunchParent笔者也不清楚。

先不管它,我们再看日志,发现运行到了下面这个函数,它打算启动XMLRPC服务器端。

所以调用的顺序是:roslaunch_ init _.py文件中的main()函数调用parent.pystart()函数,start()函数调用自己类中的_start_infrastructure()函数,_start_infrastructure()函数调用自己类中的_start_server()函数,_start_server()函数再调用server.py中的start函数。

def _start_server(self):
        self.logger.info("starting parent XML-RPC server")
        self.server = roslaunch.server.ROSLaunchParentNode(self.config, self.pm)
        self.server.start()

我们再进到server.py文件中,找到ROSLaunchNode类,里面的start函数又调用了父类XmlRpcNode中的start函数。

class ROSLaunchNode(xmlrpc.XmlRpcNode):
    """
    Base XML-RPC server for roslaunch parent/child processes
    """
    def start(self):
        logger.info("starting roslaunch XML-RPC server")
        super(ROSLaunchNode, self).start()

我们来到ros_comm-noetic-develtoolsrosgraphsrcrosgraph路径,找到xmlrpc.py文件。找到class XmlRpcNode(object)类,再进入start(self)函数,发现它调用了自己类的run函数,run函数又调用了自己类中的_run函数,_run函数又调用了自己类中的_run_init()函数,在这里才调用了真正起作用的ThrengXMLRPCServer类。

因为master节点是用python实现的,所以,需要有python版的XMLRPC库。

幸运的是,python有现成的XMLRPC库,叫pleXMLRPCServer。SimpleXMLRPCServer已经内置到python中了,无需安装。

所以,ThreadingXMLRPCServer类直接继承了SimpleXMLRPCServer,如下。

class ThreadingXMLRPCServer(socketserver.ThreadingMixIn, SimpleXMLRPCServer)
文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。