不同进程间进行通讯的方式很多,对于Python实现的系统来说,如果想通过RPC方式进行通讯,那么可以考虑选用 RPyC 这个框架。
安装RPyC
RPyC可以通过pip直接进行安装,
pip install rpyc
两种启动模式
RPC操作需要掉用方与被调用方,在RPyC里面需要启动对应的Server,Client在连接上Server之后,双方可以互相调用。
classic
RPyC经典启动模式中,进程之间完全“信任”,可以直接调用进程上的方法。
# 启动server,在rpyc/bin目录下
python rpyc_classic.py
# 客户端进行连接
import rpyc
conn = rpyc.classic.connect("localhost")
# 通过conn.modules访问server进程内的module
print conn.modules.sys
service
RPyC新版里面提供了另外一种Server启动模式,服务端通过定义Service类来向Client暴露接口。
Server端代码,exposed_前缀申明的成员函数可以被Client直接访问。
# -*- encoding:utf-8 -*-
from rpyc.utils.classic import SlaveService
from rpyc.utils.server import ThreadedServer
class ServerService(SlaveService):
def on_connect(self):
print 'on_connect'
def on_disconnect(self):
print 'on_disconnect'
def exposed_get_answer(self):
return 42
if __name__ == '__main__':
server = ThreadedServer(ServerService, port=18861, hostname="0.0.0.0")
server.start()
对应的Client代码,
conn = rpyc.connect('127.0.0.1', 18861, config={'allow_all_attrs': True})
conn.root.get_answer()
数据传递
Client与Server之间调用函数时可以像调用本地函数一样直接传递各种参数。不过需要注意的是传递过去后接收方拿到的数据类型。Theory of Operation 这个文档里面介绍了,在RPyC调用过程中,数据通过两种方式进行传递,
- By Value。简单的内置类型等通过By Value方式进行传递。
- By Reference。其余对象类型同过By Reference方式进行传递。接收方实际获取到的数据类型为netref (network reference)。
对于By Reference传递过来的对象,在一些处理上要特别注意,避免因为实际对象类型是netref造成的问题。