基本上我们可以按照以下方式调用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()
我跟随,有点新手,问题:
result = s.system.listmethods()
会阻止龙卷风? result = yield gen.Task(s.system.listmethods)
?答案 0 :(得分:3)
1.是的,它会阻止龙卷风,因为xmlrpclib使用阻塞的python套接字(原样)
2.不是我知道的,但我会提供一个解决方案,你可以保留xmlrpclib,但让它同步
3.我的解决方案不使用龙卷风。
好的,所以每当你进行网络连接并且需要编写异步代码时,请记住一个有用的库是gevent,这是一个非常好的高质量库,我建议大家。
为什么它好用且易于使用?
所有你需要做的就是猴子补丁,只有一个简单的界限:
来自gevent import monkey; monkey.patch_all()
使用龙卷风时,你需要知道两件事(你可能已经知道):
好的,这是一个例子,说明了与龙卷风进行必要的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。