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)
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。