为什么透视论证是一种pb.可视没有通过?

2024-04-25 23:25:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图了解如何让服务器知道哪个客户端正在twisted的透视代理中发出远程请求。我想我应该使用twisted.spread.pb.Viewable来实现这个,但是当我在Viewable的view_*方法中尝试透视参数时,它是None。你知道吗

我运行这个服务器

import twisted.spread.pb as pb
import twisted.internet.reactor as reactor

class Server(pb.Root):
    def __init__(self):
        self.v = MyViewable()

    def remote_getViewable(self):
        return self.v

class MyViewable(pb.Viewable):
    def view_foo(self, perspective):
        print ("Perspective %s"%perspective)


if __name__ == "__main__":
    reactor.listenTCP(54321, pb.PBServerFactory(Server()))
    print("Starting reactor")
    reactor.run()

这个客户呢

import twisted.spread.pb as pb
import twisted.internet.reactor as reactor
from twisted.internet.defer import inlineCallbacks

@inlineCallbacks
def gotRoot(root):
    v1 = yield root.callRemote("getViewable")
    v2 = yield root.callRemote("getViewable")
    print(v1)
    print(v2)
    yield v1.callRemote("foo")
    yield v2.callRemote("foo")

factory = pb.PBClientFactory()
reactor.connectTCP("localhost", 54321, factory)
d = factory.getRootObject()
d.addCallback(gotRoot)
reactor.run()

服务器的输出是

Starting reactor
Perspective None
Perspective None

为什么这些观点都没有?你知道吗


Tags: importself服务器nonedefastwistedinternet
1条回答
网友
1楼 · 发布于 2024-04-25 23:25:59

通过实验,我相信我已经找到了答案。你知道吗

为了远程调用pb.可视要正确接收perspective参数,必须从对的实例调用的perspective方法中获取对客户端持有的可视对象的引用作为返回值头像(或子类)。然后,传递到view方法的perspective参数对应于最初向客户机提供对可视对象的引用的化身。你知道吗

原始发布中的示例代码无法正常工作,因为对可视对象的远程引用是从铅根,而不是作为头像. 你知道吗

我在这里注意到,虽然这个信息是通过examples in the official documents的编写方式隐含的,但是似乎没有在那里明确地说明。你知道吗

编辑:我找到了正确的方法。领域的requstAvatar方法的参数之一是用户的mind。您所要做的就是将mind.perspective设置为新的Avatar实例,所有后续的远程调用都按您所期望的方式工作。例如:

class SimpleRealm:
implements(IRealm)

def requestAvatar(self, avatarId, mind, *interfaces):
    avatar = MyAvatarSubclass()
    mind.perspective = avatar
    return pb.IPerspective, avatar, avatar.logout

旧编辑(OLD EDIT):一种(糟糕的)方法是显式构造一个pb.ViewPoint并将其作为参数传递给远程客户端。例如,如果p是Avatar子类的实例,而v是服务器端的可视对象,那么我们可以在服务器端执行此操作

referenceToClient.callRemote("take", ViewPoint(p, v))

在客户方面,我们有

def remote_take(self, objToReceive):
    self.myView = objToReceive

客户机随后对self.myView.callRemote(...)的调用将正常工作

相关问题 更多 >