完成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
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类。
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)
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
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端的运用方式如下。
16
17
18
19
20
21
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类的完成如下。
class RPCServer(TCPServer, JSONRPC, RPCStub):
TCPServer.init(self)
JSONRPC.init(self)
RPCStub.init(self)
RPCServer继承自TCPServer、JSONRPC、RPCStub,这些类同样完成在rpcserver.py文件中并且给出了细致的注释,所以就细致解释了。