2012-01-25 22 views
0

我有一個簡單的「回聲」 PB客戶端和服務器,其中客戶端發送的對象,其回聲相同的對象返回到客戶端的服務器:twisted:如何使用Perspective Broker發送和接收同一個對象?

客戶端:

from twisted.spread import pb 
from twisted.internet import reactor 
from twisted.python import util 
from amodule import aClass 

factory = pb.PBClientFactory() 
reactor.connectTCP("localhost", 8282, factory) 
d = factory.getRootObject() 

d.addCallback(lambda object: object.callRemote("echo", aClass())) 
d.addCallback(lambda response: 'server echoed: '+response) 
d.addErrback(lambda reason: 'error: '+str(reason.value)) 
d.addCallback(util.println) 

d.addCallback(lambda _: reactor.stop()) 
reactor.run() 

服務器:

from twisted.application import internet, service 
from twisted.internet import protocol 
from twisted.spread import pb 
from amodule import aClass 

class RemoteClass(pb.RemoteCopy, aClass): 
    pass 
pb.setUnjellyableForClass(aClass, RemoteClass) 

class PBServer(pb.Root): 
    def remote_echo(self, a): 
     return a 

application = service.Application("Test app") 

# Prepare managers 
clientManager = internet.TCPServer(8282, pb.PBServerFactory(PBServer())); 
clientManager.setServiceParent(application) 

if __name__ == '__main__': 
    print "Run with twistd" 
    import sys 
    sys.exit(1) 

的ACLASS是一個簡單的類實現可複製: 從twisted.spread進口PB

class aClass(pb.Copyable): 
    pass 

當運行上述代碼中,我得到這個錯誤: twisted.spread.jelly.InsecureJelly:模塊內建不允許(在類型內置 .RemoteClass)。

實際上,由於在服務器端使用pb.setUnjellyableForClass(aClass,RemoteClass)進行了安全保護,所以該對象沒有任何問題地發送到服務器,但是一旦它返回給客戶端,就會引發該錯誤。

我正在尋找一種簡單的方法來發送/接收兩個同伴之間的對象。

回答

3

透視代理通過網絡通過名稱來識別類。一個類的名稱部分來自於它定義的模塊。定義從命令行運行的文件中的類(即,「主要腳本」)的一個棘手問題是,它們最終會以令人驚訝的名字命名。當你這樣做:

python foo.py 

模塊名稱的Python給人以代碼foo.py"foo"如人們所期望的那樣。相反,它是這樣的"__main__"(這就是爲什麼if __name__ == "__main__":技巧的作品)。

但是,如果你的應用程序的其它部分稍後嘗試從foo.py進口的東西,那麼Python 重新評估其內容創建一個名爲"foo"一個模塊。

此外,一個進程的"__main__"模塊中定義的類可能與另一個進程的"__main__"模塊中定義的類無關。在您的示例中就是這種情況,其中__main__.RemoteClass在您的服務器進程中定義,但客戶端進程的__main__模塊中沒有RemoteClass

因此,PB會混淆並無法完成對象轉移。

解決方案是儘量減少主腳本中的代碼數量,特別是永遠不要用名稱來定義事物(沒有類別,沒有函數定義)。

但是,另一個問題是期望RemoteCopy可以通過PB發送,無需額外的準備工作。可以發送一個Copyable,在對等體上創建RemoteCopy,但這不是對稱關係。您的客戶還需要通過撥打類似(或不同)的pb.setUnjellyableForClass電話來實現此目的。

+0

我已經從server.py中刪除了類,並將它們放入了amodule.py,這裏是我的新文件內容:server.py:http://codepad.org/fRZTwgKI amodule.py:http:// codepad。 org/h9rON50E 沒有任何變化,我仍然得到果凍錯誤 –

相關問題