1

サーバーがツイストのパースペクティブ ブローカーでリモート リクエストを行っているクライアントを認識できるようにする方法を理解しようとしています。私は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

パースペクティブ引数が None なのはなぜですか?

4

1 に答える 1

0

実験を通して、私は答えを決定したと信じています。

pb.Viewable での view_* メソッドのリモート呼び出しがパースペクティブ引数を適切に受け取るためには、クライアントが保持するその Viewable への参照が、pb のインスタンスで呼び出された perspective_* メソッドからの戻り値として取得されている必要があります。 .アバター (またはサブクラス)。view_* メソッドに渡されたパースペクティブ引数は、最初にクライアントに Viewable への参照を与えた Avatar に対応します。

Viewable へのリモート参照は、pb.Avatar の perspective_* メソッドからの戻り値としてではなく、pb.Root からクライアントに渡されるため、元の投稿のサンプル コードは正しく機能しません。

この情報は、公式文書の例が書かれている方法によって暗示されていますが、そこには明示的に述べられていないようです。

編集:これを行う正しい方法を見つけました。Realm のrequstAvatarメソッドへの引数の 1 つは、ユーザーのmind. 新しい Avatar インスタンスに設定mind.perspectiveするだけで、その後のすべてのリモート呼び出しが期待どおりに機能します。例えば:

class SimpleRealm:
implements(IRealm)

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

OLD EDIT : これを機能させる (厄介な) 方法は、 a を明示的に構築し、pb.ViewPointそれを引数としてリモート クライアントに渡すことです。たとえばp、アバター サブクラスのインスタンスでありv、サーバー側で表示可能な場合、サーバー上でこれを行うことができます

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

クライアント側のどこに次のようなものがありますか

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

クライアントによるその後の呼び出しはself.myView.callRemote(...)適切に機能します

于 2013-11-20T01:40:42.627 に答える