作者:杨冬 欢迎转载,也请保留这段声明。谢谢!
出处:https://andyyoung01.github.io/ 或 http://andyyoung01.16mb.com/
RPyC(Remote Python Call)是用于远程过程调用,集群和分布式计算的python库。RPyC克服了进程和计算机之间的物理界限,使得操作远程对象就像操作本地对象一样。
使用rpyc编写c/s结构程序,完全不用考虑老式的socket编程,现在只用编写简单的3、5行代码即可完成以前多行代码完成的功能。在RPyC 3.0版之后,其提供了一种基于服务的新的RPyC编程模型。基本上,一个服务有如下的模板代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import rpyc class MyService(rpyc.Service): def on_connect(self): pass def on_disconnect(self): pass def exposed_get_answer(self): return 42 def get_question(self): return "what is the airspeed velocity of an unladen swallow?" if __name__ == "__main__": from rpyc.utils.server import ThreadedServer t = ThreadedServer(MyService, port = 18861) t.start()
|
上面的代码有几点需要注意:
- 自定义的服务类需继承自rpyc.Service类,类的名称应该以Service结尾,这种命名方式便于对服务进行注册。上面的代码将MyService类注册了一个名称为“my“的服务。
- 可以自定义服务的初始化/结束代码,如上面的
on_connect
和on_disconnect
方法。
- 方法名以
exposed_
开始的方法可以被远程访问到,其它的方法不能被远程访问。例如上面例子的exposed_get_answer
方法,客户端可以通过名称get_answer
远程调用,但是客户端调用不了 get_question
方法。
在客户端,服务被暴露为连接的root对象,下面看一下客户端的调用实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| >>> import rpyc >>> c = rpyc.connect("localhost", 18861) >>> c.root <__main__.MyService object at 0x7ff294269948> >>> c.root.get_answer <bound method MyService.exposed_get_answer of <__main__.MyService object at 0x7ff294269948>> >>> c.root.get_answer() 42 >>> c.root.exposed_get_answer() 42 >>> c.root.get_question() Traceback (most recent call last): ... _get_exception_class.<locals>.Derived: 'MyService' object has no attribute 'exposed_get_question' ========= Remote Traceback (1) ========= Traceback (most recent call last): File "/home/yangdong/python_env/py352/lib/python3.5/site-packages/rpyc/core/protocol.py", line 305, in _dispatch_request res = self._HANDLERS[handler](self, *args) ... AttributeError: 'MyService' object has no attribute 'exposed_get_question'
|
通过上面的实例可见通过RPyC编写远程过程调用是多么得简单。
RPyC不仅仅对Socket进行了封装,它还支持同步与异步操作、回调和远程服务以及透明的对象代理,可以在Server与Client之间传递Python的任意对象,性能也比较高效。可以参考官方文档的教程进行更多了解。