Python远程方法调用实现过程解析
RPCHandler和RPCProxy的基本思路是很比较简单的。如果一个客户端想要调用一个远程函数,比如foo(1,2,z=3),代理类创建一个包含了函数名和参数的元组(‘foo',(1,2),{‘z':3})。这个元组被pickle序列化后通过网络连接发生出去。这一步在RPCProxy的getattr()方法返回的do_rpc()闭包中完成。
服务器接收后通过pickle反序列化消息,查找函数名看看是否已经注册过,然后执行相应的函数。执行结果(或异常)被pickle序列化后返回发送给客户端。实例需要依赖multiprocessing进行通信。不过,这种方式可以适用于其他任何消息系统。例如,如果你想在ZeroMQ之上实习RPC,仅仅只需要将连接对象换成合适的ZeroMQ的socket对象即可。
先实现server端
importjson
frommultiprocessing.connectionimportListener
fromthreadingimportThread
classRPCHandler:
def__init__(self):
self._functions={}
defregister_function(self,func):
self._functions[func.__name__]=func
defhandle_connection(self,connection):
try:
whileTrue:
func_name,args,kwargs=json.loads(connection.recv())
#RuntheRPCandsendaresponse
try:
r=self._functions[func_name](*args,**kwargs)
connection.send(json.dumps(r))
exceptExceptionase:
connection.send(json.dumps(e))
exceptEOFError:
pass
defrpc_server(handler,address,authkey):
sock=Listener(address,authkey=authkey)
whileTrue:
client=sock.accept()
t=Thread(target=handler.handle_connection,args=(client,))
t.daemon=True
t.start()
#Someremotefunctions
defadd(x,y):
returnx+y
if__name__=='__main__':
handler=RPCHandler()
handler.register_function(add)
#Runtheserver
rpc_server(handler,('127.0.0.1',17000),authkey=b'peekaboo')
再实现client端
importjson
frommultiprocessing.connectionimportClient
classRPCProxy:
def__init__(self,connection):
self._connection=connection
def__getattr__(self,name):
defdo_rpc(*args,**kwargs):
self._connection.send(json.dumps((name,args,kwargs)))
result=json.loads(self._connection.recv())
ifisinstance(result,Exception):
raiseresult
returnresult
returndo_rpc
if__name__=='__main__':
c=Client(('127.0.0.1',17000),authkey=b'peekaboo')
proxy=RPCProxy(c)
res=proxy.add(2,3)
print(res)
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。