>From some experimentation I find that the only way to make a Viewable
get a meaningful perspective argument when executing view_* methods is
to make sure that the references to that Viewable are given to clients
as return values from perspective_* methods called on a pb.Avatar.

In particular, if the Avatar gives a client a reference to a Viewable
by passing it as an argument to a remote_* method on the client,
subsequent invocations of view_* methods by the client result in
perspective argument in view_* methods being None.

I have attached a complete working example of a client and server that
succinctly illustrates this issue.

Question: Is there a way to distribute un-asked for references to
Viewables that properly get the perspective argument in their view_*
methods?

Sincerely,
Daniel Sank
#!/usr/bin/env python

from twisted.spread import pb
from twisted.internet import reactor
from twisted.cred import credentials

class Client(pb.Referenceable):

    def connect(self):
        factory = pb.PBClientFactory()
        reactor.connectTCP("localhost", 8800, factory)
        def1 = factory.login(credentials.UsernamePassword("alice", "1234"),
                             client=self)
        def1.addCallback(self.connected)
        reactor.run()

    def connected(self, perspective):
        self.perspective = perspective
        d = perspective.callRemote("getViewable")
        d.addCallback(self.gotViewable)
    
    def gotViewable(self, v):
        v.callRemote("test", "RETURNED FROM")
    
    def remote_takeViewable(self, v):
        v.callRemote("test", "SENT BY")

Client().connect()
#!/usr/bin/env python

from zope.interface import implements

from twisted.cred import portal, checkers
from twisted.spread import pb
from twisted.internet import reactor

class MyViewable(pb.Viewable):
    def view_test(self, perspective, description):
        print("This viewpoint was %s the Avatar"%description)
        print("and we got the following perspective: %s"%perspective)


class MyRealm(object):
    implements(portal.IRealm)
    def requestAvatar(self, avatarID, mind, *interfaces):
        assert pb.IPerspective in interfaces
        avatar = User(avatarID, mind)
        return pb.IPerspective, avatar, lambda a=avatar:a.logout()


class User(pb.Avatar):
    def __init__(self, name, mind):
        self.name = name
        self.mind = mind
        self.v = MyViewable()
        mind.callRemote("takeViewable", self.v)

    def perspective_getViewable(self):
        return self.v

    def logout(self):
        self.mind = None


realm = MyRealm()
checker = checkers.InMemoryUsernamePasswordDatabaseDontUse()
checker.addUser("alice", "1234")
p = portal.Portal(realm, [checker])

reactor.listenTCP(8800, pb.PBServerFactory(p))
reactor.run()
_______________________________________________
Twisted-Python mailing list
Twisted-Python@twistedmatrix.com
http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python

Reply via email to