Python twisted:如何使用透视代理发送和接收相同的对象?
我有一个简单的“echo”PB客户端和服务器,客户端向服务器发送一个对象,服务器将相同的对象回显到客户端:Python twisted:如何使用透视代理发送和接收相同的对象?,python,serialization,twisted,perspective,broker,Python,Serialization,Twisted,Perspective,Broker,我有一个简单的“echo”PB客户端和服务器,客户端向服务器发送一个对象,服务器将相同的对象回显到客户端: 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,
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.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.unsecurejelly:Module内置不允许(在type内置.RemoteClass中)
事实上,对象被发送到服务器时没有任何问题,因为它在服务器端由pb.setUnjellyableForClass(aClass,RemoteClass)保护,但一旦它返回到客户端,就会引发该错误
我正在寻找一种在两个对等方之间发送/接收我的对象的简便方法。当通过网络谈论类时,透视代理按名称识别类。类的名称部分来自定义它的模块。在从命令行(即“主脚本”)运行的文件中定义类的一个棘手问题是,它们可能会以一个令人惊讶的名称结束。执行此操作时:
python foo.py
Python给foo.py
中的代码起的模块名并不像人们所期望的那样是“foo”
。相反,它类似于“\uuuuuu main\uuuuuuu”
(这就是为什么如果
技巧有效的原因)
但是,如果应用程序的其他部分稍后尝试从foo.py
导入某些内容,那么Python将重新计算其内容,以创建一个名为“foo”
的新模块
此外,在一个进程的“\uuuuuu main\uuuuuuuu”
模块中定义的类可能与另一个进程的“\uuuuuuuuuu main\uuuuuuuuu”模块中定义的类无关。在您的示例中就是这种情况,其中在服务器进程中定义了\uuuuu main\uuuu.RemoteClass
,但在客户端进程的\uuuuu main\uuuu
模块中没有RemoteClass
因此,PB混淆了,无法完成对象传输
解决方案是将主脚本中的代码量保持在最低限度,尤其是不要在主脚本中定义名称(没有类,没有函数定义)
然而,另一个问题是,可以通过PB发送RemoteCopy
,而无需额外准备。可以发送Copyable
,在对等机上创建RemoteCopy
,但这不是对称关系。您的客户端还需要通过调用类似(或不同)的pb.setUnjellyableForClass来实现这一点。当通过网络谈论类时,透视代理按名称识别类。类的名称部分来自定义它的模块。在从命令行(即“主脚本”)运行的文件中定义类的一个棘手问题是,它们可能会以一个令人惊讶的名称结束。执行此操作时:
python foo.py
Python给foo.py
中的代码起的模块名并不像人们所期望的那样是“foo”
。相反,它类似于“\uuuuuu main\uuuuuuu”
(这就是为什么如果
技巧有效的原因)
但是,如果应用程序的其他部分稍后尝试从foo.py
导入某些内容,那么Python将重新计算其内容,以创建一个名为“foo”
的新模块
此外,在一个进程的“\uuuuuu main\uuuuuuuu”
模块中定义的类可能与另一个进程的“\uuuuuuuuuu main\uuuuuuuuu”模块中定义的类无关。在您的示例中就是这种情况,其中在服务器进程中定义了\uuuuu main\uuuu.RemoteClass
,但在客户端进程的\uuuuu main\uuuu
模块中没有RemoteClass
因此,PB混淆了,无法完成对象传输
解决方案是将主脚本中的代码量保持在最低限度,尤其是不要在主脚本中定义名称(没有类,没有函数定义)
然而,另一个问题是,可以通过PB发送RemoteCopy
,而无需额外准备。可以发送Copyable
,在对等机上创建RemoteCopy
,但这不是对称关系。您的客户端还需要通过进行类似(或不同)的pb.setUnjellyableForClass
调用来实现这一点。我已经从server.py中删除了这些类,并将它们放入了amodule.py,以下是我的新文件内容:server.py:amodule.py:未更改,我仍然收到jelly错误我已经从server.py中删除了类并将它们放入amodule.py,这是我的新文件内容:server.py:amodule.py:没有更改,我仍然收到jelly错误