Python中實(shí)現(xiàn)遠(yuǎn)程調(diào)用(RPC、RMI)簡單例子
遠(yuǎn)程調(diào)用使得調(diào)用遠(yuǎn)程服務(wù)器的對象、方法的方式就和調(diào)用本地對象、方法的方式差不多,因?yàn)槲覀兺ㄟ^網(wǎng)絡(luò)編程把這些都隱藏起來了。遠(yuǎn)程調(diào)用是分布式系統(tǒng)的基礎(chǔ)。
遠(yuǎn)程調(diào)用一般分為兩種,遠(yuǎn)程過程調(diào)用(RPC)和遠(yuǎn)程方法調(diào)用(RMI)。
RPC
RPC屬于函數(shù)級別的遠(yuǎn)程調(diào)用,其多是通過HTTP傳輸數(shù)據(jù),數(shù)據(jù)形式有XML、JSON、序列化數(shù)據(jù)等。在此,用python做一個(gè)xml-rpc的示例。 先給服務(wù)器端server.py:
from SimpleXMLRPCServer import SimpleXMLRPCServer
def add(x, y):
return x + y
if __name__ == '__main__':
s = SimpleXMLRPCServer(('127.0.0.1', 8080))
s.register_function(add)
s.serve_forever()
s是一個(gè)綁定了本地8080端口的服務(wù)器對象,register_function()方法將函數(shù)add注冊到s中。serve_forever()啟動(dòng)服務(wù)器。 再給個(gè)客戶端client.py:
from xmlrpclib import ServerProxy
if __name__ == '__main__':
s = ServerProxy("http://127.0.0.1:8080")
print s.add(3,4)
現(xiàn)在,運(yùn)行server.py,然后運(yùn)行client.py,client.py所在的console會輸出7。
我們用wireshark看一下這期間傳遞的數(shù)據(jù)是什么樣子的,請求的數(shù)據(jù):
<?xml version='1.0' ?>
<methodCall>
<methodName>
add
</methodName>
<params>
<param>
<value>
<int> 3 </int>
</value>
</param>
<param>
<value>
<int> 4 </int>
</value>
</param>
</params>
</methodCall>
響應(yīng)的數(shù)據(jù):
<?xml version='1.0' ?>
<methodResponse>
<params>
<param>
<value>
<int> 7 </int>
</value>
</param>
</params>
</methodResponse>
好吧,言簡意賅,不做贅述。
RMI
RMI意為遠(yuǎn)程方法調(diào)用,粒度比RPC要大,因?yàn)樗幕締挝皇菍ο?。其大致思路是這樣的:創(chuàng)建RMI服務(wù)器對象,將實(shí)例化的某個(gè)對象以指定的服務(wù)名稱(也可以是多個(gè)對象,但是服務(wù)名稱不應(yīng)相同)注冊到RMI服務(wù)器對象中,之后啟動(dòng)RMI服務(wù)器。服務(wù)器等待客戶端發(fā)送的數(shù)據(jù)(包括服務(wù)名稱、函數(shù)名、參數(shù)),將處理結(jié)果返回給客戶端。 Pyro4是一個(gè)基于python的RMI實(shí)現(xiàn),下面我們用Pyro4創(chuàng)建一個(gè)RMI服務(wù)器,請看server2.py:
import Pyro4
class GreetingMaker(object):
def get_fortune(self, name):
return "Hello, {0}. \n" .format(name)
greeting_maker=GreetingMaker()
daemon=Pyro4.Daemon()
uri=daemon.register(greeting_maker)
print "Ready. Object uri =", uri
daemon.requestLoop()
uri變量是Pyro4用自己的方法為greeting_maker對象生成的uri,其中包括套接字以及為greeting_maker生成的唯一的id。這個(gè)id相當(dāng)于服務(wù)名稱,當(dāng)然也可以指定更易懂的服務(wù)名稱。下面是客戶端client2.py:
import Pyro4
uri=raw_input(" Pyro uri : ").strip()
name=raw_input("Your name: ").strip()
greeting_maker=Pyro4.Proxy(uri)
print greeting_maker.get_fortune(name)
這其中要輸入的uri也就是server2.py生成的uri。通過給Pyro4.Proxy傳遞greeting_maker的uri,可以認(rèn)為和服務(wù)器端的greeting_maker建立的連接,然后調(diào)用greeting_maker的get_fortune()方法。如果name是letian,那么print greeting_maker.get_fortune(name)的結(jié)果是Hello, letian.。
相關(guān)文章
python3實(shí)現(xiàn)公眾號每日定時(shí)發(fā)送日報(bào)和圖片
這篇文章主要為大家詳細(xì)介紹了python3實(shí)現(xiàn)公眾號每日定時(shí)發(fā)送日報(bào)和圖片,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-02-02在多種情況/開發(fā)環(huán)境中運(yùn)行python腳本和代碼的技巧分享
Python腳本或程序是包含可執(zhí)行Python代碼的文件,能夠運(yùn)行Python腳本和代碼可能是您作為Python開發(fā)人員所需的最重要的技能,在本教程中,您將學(xué)習(xí)一些運(yùn)行Python腳本和代碼的技術(shù),在每種情況下使用的技術(shù)將取決于您的環(huán)境、平臺、需求和技能2023-11-11python:目標(biāo)檢測模型預(yù)測準(zhǔn)確度計(jì)算方式(基于IoU)
今天小編就為大家分享一篇python:目標(biāo)檢測模型預(yù)測準(zhǔn)確度計(jì)算方式(基于IoU),具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-01-01淺談Python從全局與局部變量到裝飾器的相關(guān)知識
今天給大家?guī)淼氖顷P(guān)于Python的相關(guān)知識,文章圍繞著Python從全局與局部變量到裝飾器的相關(guān)知識展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下2021-06-06Python實(shí)現(xiàn)王者榮耀自動(dòng)刷金幣的完整步驟
這篇文章主要介紹了Python實(shí)現(xiàn)王者農(nóng)藥自動(dòng)刷金幣的完整步驟,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01python利用OpenCV2實(shí)現(xiàn)人臉檢測
這篇文章主要為大家詳細(xì)介紹了python利用OpenCV2實(shí)現(xiàn)人臉檢測,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12opencv+python實(shí)現(xiàn)圖像矯正
這篇文章主要為大家詳細(xì)介紹了opencv+python實(shí)現(xiàn)圖像矯正,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08