今天我們來實(shí)現(xiàn)一個簡單的rpc調(diào)用绑雄,首先是一個簡單的例子:
from xmlrpc.server import SimpleXMLRPCserver
class KeyValueServer:
_rpc_methods_ = ['get', 'set', 'delete', 'exits', 'keys']
def __init__(self, address):
self._data = []
self._serv = SimpleXMLPRCServer(address, allow_none=True)
for name in self._rpc_methods_:
self._serv.regist_function(getattr(self, name))
def get(self, name):
return self._data[name]
def set(self, name, value):
self._data[name] = value
def delete(self, name):
self._data[name]
def exits(self, name):
return name in self._data
def keys(self):
return list(self._data)
def serve_forever(self):
self._serv.serve_forever()
if "__name__" == "__main__":
kvserv = KeyValueServer(('', 15000))
kvserv.serve_forever()
這里的這個簡單例子是建立一個rpc的服務(wù)端烦绳,關(guān)鍵點(diǎn)主要有以下幾點(diǎn):
- rpc_methods為自己定義的方法集窄驹,可以在里面添加我們需要自定義的方法。
- 實(shí)例化服務(wù)端之后翎蹈,切記把我們自己定義的方法注冊到服務(wù)端,這里的注冊使用循環(huán)獲取自己的屬性來實(shí)現(xiàn),不清楚getattr的同學(xué)可以自己學(xué)習(xí)一下這個常用的方法。
- 最后就是啟動服務(wù)serve_forever()方法懂昂。
寫完了服務(wù)端的代碼,那么我們繼續(xù)來編寫客戶端的代碼没宾,看一下客戶端如何調(diào)用服務(wù)器的代碼:
from xmlrpc.client import ServerProxy
s = ServerProxy('http://localhost:15000', allow_none=True)
s.set('foo', 'bar')
s.set('spam', [1,2,3])
就這么簡單的代碼可以創(chuàng)建一個端的代理凌彬,在這個代理的實(shí)例上面可以進(jìn)行屬性設(shè)置,其實(shí)已經(jīng)通過內(nèi)部實(shí)現(xiàn)進(jìn)行遠(yuǎn)程調(diào)用了循衰,從我們的視角看來就行是在本地端調(diào)用一樣铲敛。
我們可以這樣進(jìn)行調(diào)用:
>>>s.keys()
['foo', 'spam']
還可以使用get, 等一些列自定義方法。
再來分析一下我們的這個遠(yuǎn)程調(diào)用代碼会钝,這個調(diào)用的瓶頸在于性能伐蒋,因?yàn)榉?wù)器端是已單線程實(shí)現(xiàn)的,也許你會說我可以已多線程的方式運(yùn)行迁酸,但是這個RPC會將所有的數(shù)據(jù)進(jìn)行XML化先鱼,所以稍微慢一點(diǎn),如果從實(shí)用性的角度來看的話奸鬓,你需要馬上有一個并且可以不完善的遠(yuǎn)程調(diào)用時焙畔,這是個不錯的選擇。
下一節(jié)我們來看如何實(shí)現(xiàn)遠(yuǎn)端調(diào)用的過程串远。