完成jsonrpc
在完成前,简单理一下整体思绪。
1、Network Service 直接运用Python Socket相关的API完成 2.传输数据运用JSON,在Socket层会被压成二进制,我们无需关怀。
模拟xmlrpc,Client与Server都采用Minix多继承机制来完成,每个类担任本身的事情,最终暴显露现的只要一个类中有限的办法。
先从Client端开端完成。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | # client.py import rpcclient c = rpcclient.RPCClient() c.connect('127.0.0.1', 5000) res = c.add(1, 2, c=3) print(f'res: [{res}]') |
实例化rpcclient.RPCClient类,然后调用connect办法链接Server端,随后直接调用Server端的add办法,该办法的效果就是将传入的数据停止累加并将累加的结果返回,最后将add办法返回的结果打印出了。
RPCClient类继承于TCPClient类与RPCStub类。
1 2 3 4 5 | # rpclient.py class RPCClient(TCPClient, RPCStub): pass |
其中TCPClient担任经过Socket完成TCP链接并将数据恳求过去,而RPCStub类主要将Client端调用Server端办法的相关信息打包,然后调用TCPClient类中的办法发送则可,两个类同样完成在rpclient.py文件中,代码如下。
lass TCPClient(object): def __init__(self): self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) def connect(self, host, port): '''链接Server端''' self.sock.connect((host, port)) def send(self, data): '''将数据发送到Server端''' self.sock.send(data) def recv(self, length): '''承受Server端回传的数据''' return self.sock.recv(length) class RPCStub(object): def __getattr__(self, function): def _func(*args, **kwargs): d = {'method_name': function, 'method_args': args, 'method_kwargs': kwargs} self.send(json.dumps(d).encode('utf-8')) # 发送数据 data = self.recv(1024) # 接纳办法执行后返回的结果 return data setattr(self, function, _func) return _func |
TCPClient类就是常规的Socket API的操作,无需多言,主要看看RPCStub类。
当我们在Client端调用res = c.add(1, 2, c=3)时,会执行RPCStub中的__getattr__办法,该办法会将Client端调用的办法、参数等信息经过TCPServer类的send办法发送,发送数据停止了JSON格式化,便当Server端解码,随后便调用recv办法等候Server端相应的数据返回。
由于RPCClient类自身没有add办法,为了让用户做到Client端直接调用Server端办法的方式,先应用__getattr__构建了_func办法,并将其经过setattr办法设置到RPCClient类中,此时该类就有Server端办法对应的映射了。
调用add办法,就调用了对应的_func办法,将数据发送至Server端。
Client端就这样搞定了,接着来完成Server端,不用慌张,十分简单。
Server端的运用方式如下。
9 10 11 12 13 14 15 16 17 18 19 20 21 | # server.py import rpcserver def add(a, b, c=10): sum = a + b + c return sum s = rpcserver.RPCServer() s.register_function(add) # 注册办法 s.loop(5000) # 传入要监听的端口 |
实例化rpcserver.RPCServer类,然后经过register_function办法将想被Client端调用的办法传入,随后调用loop办法,将要监听的端口传入,RPCServer类的完成如下。
7 8 9 10 11 12 13 14 15 16 17 18 19 20 2 | # rpcserver.py class RPCServer(TCPServer, JSONRPC, RPCStub): def __init__(self): TCPServer.__init__(self) JSONRPC.__init__(self) RPCStub.__init__(self) def loop(self, port): # 循环监听 5000 端口 self.bind_listen(port) print('Server listen 5000 ...') while True: self.accept_receive_close() def on_msg(self, data): return self.call_method(data) |
RPCServer继承自TCPServer、JSONRPC、RPCStub,这些类同样完成在rpcserver.py文件中并且给出了细致的注释,所以就细致解释了。
链接:https://pan.baidu.com/s/1uiaaH3rXlPZ_5pibqb6eOg]提取码:0m7t
--来自百度网盘超级会员V4的分享