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() |