[Twisted-Python] Newbie question on how to send "complex" objects over the wire

Franz Zieher franz.zieher at gmail.com
Wed Oct 18 17:42:16 EDT 2006


2006/10/18, Jean-Paul Calderone <exarkun at divmod.com>:
>
> On Tue, 17 Oct 2006 22:51:55 -0200, Felipe Almeida Lessa <
> felipe.lessa at gmail.com> wrote:
> >2006/10/17, Franz Zieher <franz.zieher at gmail.com>:
> >>
> >>Can anybody provide a an example on how I would best send
> >>a data structure (i.e. an ElemenTree from elementtree) over from
> >>a server to a client process. I followed somewhat the example in
> >>the documentation and used the perspective broker "pb" to send
> >>an "simple" structure (some class with simple members)
> >>
> >>When I changed to a more complex class definition, I obviously got
> >>an InsecureJelly exception.
> >>
> >>I'm sure this question must have come up a number of times. I'm new
> >>in using twisted and not everything is so obvious at the beginning to me
> >>:-(
> >
> >I don't know if it may help you, but I think you should take a look at
> >Cerealizer ( http://home.gna.org/oomadness/en/cerealizer/index.html )
> >
>
> Using this together with PB would probably be counterproductive.
>
> Jean-Paul
>
> _______________________________________________
> Twisted-Python mailing list
> Twisted-Python at twistedmatrix.com
> http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
>


Thanks for the help. I opted for Jean-Pauls suggestion.
It really allows for such a simple data transfer between a server
and a client. I included a compressed string. It very likely misses
a number of details, I post the changes again. Maybe it is helpful
for somebody else.

Franz :-)

----------- pbsimple.py

from twisted.spread import pb, jelly
from twisted.internet import reactor
import elementtree.ElementTree as ET
from path import path
import os, pickle
from StringIO import StringIO
from zlib import compress

class test:
  def __init__(self):
    x = 3.
    y = 4.
    data = ET.ElementTree()

class Bag:
  def setContent(self,content):
    # content must be serializable
    s_content = StringIO()
    pickle.dump(content,s_content)
    s_content.flush()
    self.content = compress(s_content.getvalue())

class CopyBag(Bag, pb.Copyable):
  pass

class Sender(pb.Root):
  def __init__(self, bag):
    self.bag = bag

  def remote_sendBag(self, remote):
    self.remote = remote
    d = remote.callRemote("takeBag", self.bag)
    d.addCallback(self.ok).addErrback(self.notOk)

  def ok(self, response):
    print "info: %s" % response
    d = self.remote.callRemote("finishTransfer")
    d.addErrback(self.notOk)
    return None

  def notOk(self, failure):
    if failure.type == jelly.InsecureJelly:
      print "error: InsecureJelly"
    elif failure.type == pb.PBConnectionLost:
      print "info: data transfer finished"
    else:
    print failure
    return None

def main():
  from pbsimple import CopyBag

  icae = iCAEconfig()
  bag = CopyBag()

  bag.setContent(test())
  sender = Sender(bag)

  factory = pb.PBServerFactory(sender)
  reactor.listenTCP(8789, factory)
  reactor.run()

if __name__ == '__main__':
  main()

----- pbsimpleclient.py

from twisted.spread import pb
from twisted.internet import reactor
from twisted.python import util
import os, pickle
from StringIO import StringIO
from zlib import decompress
import elementtree.ElementTree as ET

from pbsimple import Bag, CopyBag, test

class ReceiverBag(Bag,pb.RemoteCopy):
  pass

pb.setUnjellyableForClass(CopyBag, ReceiverBag)

class Receiver(pb.Referenceable):
  def remote_takeBag(self, bag):
    # deserialize the bag.content
    try:
      self.content = pickle.loads(decompress(bag.content))
      self.len = len(bag.content)
      return "data arrived safe and sound" # positive acknowledgement
    except:
      self.content = None
      self.len = 0
      print "error: data could not be de-serialized"
      reactor.stop()

  def remote_finishTransfer(self):
    print "got bag of length:", self.len
    reactor.stop()

  def requestBag(self,remote):
    print "asking server for sending the data bag"
    remote.callRemote("sendBag",self)

def getContentFromServer():

  receiver = Receiver()
  factory = pb.PBClientFactory()
  reactor.connectTCP("localhost", 8789, factory,30)
  d = factory.getRootObject()
  d.addCallback(receiver.requestBag)
  reactor.run()
  return receiver.content

if __name__ == '__main__':
  content = getContentFromServer()
  if hasattr(content,'getroot'):
    ET.dump(content)
  else:
    print content
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://twistedmatrix.com/pipermail/twisted-python/attachments/20061018/6e3c7e6d/attachment.htm 


More information about the Twisted-Python mailing list