蟒蛇。龙卷风。非阻塞xmlrpc客户端

时间:2012-11-02 08:39:00

标签: python xml-rpc tornado xmlrpclib

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

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

在龙卷风中我们可以像这样整合它:

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)

2 个答案:

答案 0 :(得分:3)

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

2.不是我知道的,但我会提供一个解决方案,你可以保留xmlrpclib,但让它同步

3.我的解决方案不使用龙卷风。

好的,所以每当你进行网络连接并且需要编写异步代码时,请记住一个有用的库是gevent,这是一个非常好的高质量库,我建议大家。

为什么它好用且易于使用?

  • 您可以以同步方式编写异步代码(这样可以轻松实现)
  • 所有你需要做的就是猴子补丁,只有一个简单的界限:

    来自gevent import monkey; monkey.patch_all()

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

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

好的,这是一个例子,说明了与龙卷风进行必要的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套接字的所有工作,因此它们可以异步使用,同时仍以同步方式编写代码(这是一个真正的好处)。

希望这会有所帮助:)

答案 1 :(得分:0)

我不这么认为。 因为Tornado拥有它自己的ioloop,但是gevent的ioloop是自由的。 因此gevent将阻止Tornado的ioloop。