【问题标题】:Python. Tornado. Non-blocking xmlrpc clientPython。龙卷风。非阻塞 xmlrpc 客户端
【发布时间】:2012-11-02 08:39:00
【问题描述】:

基本上我们可以通过以下方式调用 xmlrpc 处理程序:

import xmlrpclib
s = xmlrpclib.ServerProxy('http://remote_host/rpc/')
print s.system.listmethods()

在 tornado 中我们可以这样集成:

import xmlrpclib
import tornado.web

s = xmlrpclib.ServerProxy('http://remote_host/rpc/')

class MyHandler(tornado.web.RequestHandler):
    def get(self):
        result = s.system.listmethods()

我有以下一些新手问题:

  1. result = s.system.listmethods() 会阻止龙卷风吗?
  2. 周围是否有非阻塞 xmlrpc 客户端?
  3. 如何实现result = yield gen.Task(s.system.listmethods)

【问题讨论】:

    标签: python xml-rpc tornado xmlrpclib


    【解决方案1】:

    1.是的,它会阻止龙卷风,因为 xmlrpclib 使用阻塞 python 套接字(原样)

    2.我不知道,但我将提供一个解决方案,您可以保留 xmlrpclib 但使其异步

    3.我的解决方案不使用tornado gen。

    好的,所以当您在进行网络并需要编写异步代码时,一个有用的库是 gevent,它是一个非常好的高质量库,我会向所有人推荐。

    为什么它好用又好用?

    • 您可以以同步方式编写异步代码(这样更容易)
    • 你所要做的就是用一条简单的线做猴子补丁:

      从 gevent 导入猴子; monkey.patch_all()

    使用龙卷风时,您需要知道两件事(您可能已经知道):

    • Tornado 仅在充当 HTTPServer 时支持异步视图(异步视图不支持 WSGI)
    • 异步视图需要自行终止响应,您可以使用 self.finish() 或 self.render()(调用 self.finish())

    好的,下面是一个示例,说明您需要与 tornado 进行必要的 gevent 集成:

    # Python immports
    import functools
    
    # Tornado imports
    import tornado.ioloop
    import tornado.web
    import tornado.httpserver
    
    # XMLRpc imports
    import xmlrpclib
    
    
    # Asynchronous gevent decorator
    def gasync(func):
        @tornado.web.asynchronous
        @functools.wraps(func)
        def f(self, *args, **kwargs):
            return gevent.spawn(func, self, *args, **kwargs)
        return f
    
    
    # Our XML RPC service
    xml_service = xmlrpclib.ServerProxy('http://remote_host/rpc/')
    
    
    class MyHandler(tornado.web.RequestHandler):
        @gasync
        def get(self):
            # This doesn't block tornado thanks to gevent
            # Which patches all of xmlrpclib's socket calls
            # So they no longer are blocking
            result = xml_service.system.listmethods()
    
            # Do something here
    
            # Write response to client
            self.write('hello')
            self.finish()
    
    
    # Our URL Mappings
    handlers = [
       (r"/", MyHandler),
    ]
    
    
    def main():
        # Setup app and HTTP server
        application = tornado.web.Application(handlers)
        http_server = tornado.httpserver.HTTPServer(application)
        http_server.listen(8000)
    
        # Start ioloop
        tornado.ioloop.IOLoop.instance().start()
    
    
    if __name__ == "__main__":
        main()
    

    所以试试这个例子(显然根据你的需要调整它),你应该很高兴。

    无需编写任何额外代码,gevent 完成了修补 python 套接字的所有工作,因此它们可以异步使用,同时仍以同步方式编写代码(这是一个真正的好处)。

    希望这会有所帮助:)

    【讨论】:

    • 谢谢,会考虑使用 gevent 和可能的副作用。
    【解决方案2】:

    我不这么认为。 因为 Tornado 有自己的 ioloop,而 gevent 的 ioloop 是 libevent。 所以 gevent 会阻塞 Tornado 的 ioloop。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-16
      • 1970-01-01
      • 1970-01-01
      • 2014-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多