Re: [Pyobjc-dev] pb and pyobjc ...
Brought to you by:
ronaldoussoren
|
From: David B. <db3...@gm...> - 2007-11-12 22:46:09
|
Antonio <str...@ti...> writes:
> I've read the example in twisted documentation ,but I don't understand HOW
> make the pb client work ... this is the code:
I think more of your issues are Twisted related rather than
PyObjC/Cocoa, and you might be complicating your life by trying to
work up two learning curves at the same time. What I might suggest is
that you experiment with getting working code independent of
PyObjC/Cocoa integration, to simplify interaction problems as you get
used to Twisted and PB. Also questions at that point are probably
best handled on the Twisted mailing list where you'll likely find more
people with appropriate experience to help out.
I can't run your actual code without the other pieces, and you don't
indicate precisely what errors you're getting, but you appear to be
mixing non-PB client startup (your attempt to use Client as a
protocol, and start it with ClientCreator), with a PB client
construction (via pb.ClientFactory). Trying to use the PB code from
within an instance of a non-PB protocol object is backwards, and too
late. You're also not taking into account that getRootObject returns
a deferred since the connection may not yet have been made at the
point when the method is being called.
For PB, a connection is handled by the pb.ClientFactory factory
object, using a pb.Broker object instance as its protocol. E.g., the
"protocol" in Twisted terms for PB is the class managing share object
instances and their serialization/deserialization across the wire. So
you never replace the actual protocol for the session.
Here's a pretty minimal example of a PB client/server combination
(without authentication) that uses an echo call. I've implemented the
client as a standalone object, so you should be able to insert the
__main__ block (aside from the reactor.run) into your UI code in lieu
of your current ClientCreator() call if you like.
Here I use a standard ClientFactory object - other choices are to
subclass that object (if for example, you want to handle automatic
reconnects). Or, if you are using authentication, the factory's
login() method should be used in lieu of getRootObject, since it
handles authentication through the Portal on the server side, and its
callback eventually hands you the root object.
-- David
- - - - - - - - - - Server - - - - - - - - - -
from twisted.internet import reactor
from twisted.spread import pb
class Root(pb.Root):
def remote_echo(self, value):
return value
if __name__ == '__main__':
reactor.listenTCP(8789, pb.PBServerFactory(Root()))
reactor.run()
- - - - - - - - - - Client - - - - - - - - - -
from twisted.internet import reactor
from twisted.spread import pb
class Client(object):
def __init__(self, factory):
factory.getRootObject().addCallbacks(self.gotRoot, self.failure)
def _done(self):
reactor.stop()
def failure(self, failure):
print 'Network failure'
print failure
self._done()
def gotRoot(self, root):
self.root = root
d = self.root.callRemote('echo', 'value')
d.addCallbacks(self.echoResponse, self.failure)
def echoResponse(self, value):
print 'Echo response:', value
self._done()
if __name__ == "__main__":
factory = pb.PBClientFactory()
reactor.connectTCP("localhost", 8789, factory)
client = Client(factory)
reactor.run()
|