[Twisted-Python] MultiService puzzler

Don Smith donwsmith at gmail.com
Wed Dec 12 19:51:24 MST 2007


Ah, I realized I need to call the reference the stompClient like this '
self.stompClient'.

Unfortunately, what is returned by this:

testq = internet.TCPClient(APPVARIABLES['queue_server'],
int(APPVARIABLES['queue_port']), connections.StompClientFactory
(username='',password='',queue='/queue/test'))

is the StompClientFactory object, not the StompProtocol object which
contains the send() method.

So, any ideas on how I can reference the StompProtocol object (that is
created by the StompClientFactory) from the GetUDP object?

Thanks,

Don

On Dec 12, 2007 9:10 AM, Don Smith <donwsmith at gmail.com> wrote:

> Thanks for your response, Christian!
>
> However, this still does not work and I think it is related to the
> StompClientFactory and the StompProtocol I'm using. I'm including those at
> the end of this email so you can see what they do.
>
> I changed my GetUDP class to this:
>
> class GetUDP(DatagramProtocol):
>
>     def datagramReceived(self, datagram, address):
>         print datagram,address
>         #Send datagram to the queue server
>         stompclient.send(datagram)
>
> And I changed the instantiation to what you gave me, but I get this error
> when I get a UDP packet:
>
>         File "Agent_service_test.py", line 103, in datagramReceived
>           stompclient.send(datagram)
>       exceptions.NameError: global name 'stompclient' is not defined
>
>
> Here are my stomp classes:
>
> class StompProtocol(Protocol, stomper.Engine):
>
>     def __init__(self, username='', password='', queue=''):
>         stomper.Engine.__init__(self)
>         self.username = username
>         self.password = password
>         self.counter = 1
>         self.log = logging.getLogger("sender")
>         self.queue = queue
>
>     def connected(self, msg):
>         """Once I've connected I want to subscribe to the message queue.
>         """
>         stomper.Engine.connected(self, msg)
>
>         #self.log.info("Connected: session %s. Begining say hello." %
> msg['headers']['session'])
>         #lc = LoopingCall(self.send)
>         #lc.start(1)
>
>         f = stomper.Frame ()
>         f.unpack(stomper.subscribe(self.queue))
>
>         # ActiveMQ specific headers:
>         #
>         # prevent the messages we send comming back to us.
>         f.headers['activemq.noLocal'] = 'true'
>
>         return f.pack()
>
>
>     def ack(self, msg):
>         """Processes the received message. I don't need to
>         generate an ack message.
>
>         """
>         self.log.info("SENDER - received: %s " % msg['body'])
>         return stomper.NO_REPONSE_NEEDED
>
>
>     def send(self):
>         """Send out a hello message periodically.
>         """
>         self.log.info("Saying hello (%d)." % self.counter)
>         self.counter += 1
>
>         f = stomper.Frame()
>         f.unpack(stomper.send(self.queue, 'hello there (%d)' %
> self.counter))
>
>         # ActiveMQ specific headers:
>         #
>         f.headers['persistent'] = 'true'
>
>         self.transport.write(f.pack())
>
>
>     def connectionMade(self):
>         """Register with stomp server.
>         """
>         cmd = stomper.connect(self.username, self.password)
>         self.transport.write(cmd)
>
>
>     def dataReceived(self, data):
>         """Data received, react to it and respond if needed.
>         """
>         msg = stomper.unpack_frame(data)
>
>         returned = self.react(msg)
>
>         if returned:
>             self.transport.write(returned)
>
> class StompClientFactory(ReconnectingClientFactory):
>     def __init__(self, username='', password='',
> queue='',queue_type='',config=''):
>         self.username=username
>         self.password=password
>         self.queue=queue
>         self.queue_type=queue_type
>         self.config_file=config
>
>
>     def buildProtocol(self, addr):
>         if self.queue_type =='config':
>             return ConfigurationProtocol(self.queue,self.config_file,
> self.username, self.password)
>         else:
>             return StompProtocol(self.username, self.password, self.queue)
>
>     def clientConnectionLost(self, connector, reason):
>         """Lost connection
>         """
>         print 'Lost connection.  Reason:', reason
>
>
>     def clientConnectionFailed(self, connector, reason):
>         """Connection failed
>         """
>         print 'Connection failed. Reason:', reason
>         ReconnectingClientFactory.clientConnectionFailed(self, connector,
> reason)
>
>
> On Dec 12, 2007 8:16 AM, Christian Simms <christian.simms at gmail.com >
> wrote:
>
> > On Dec 12, 2007 12:08 AM, Don Smith < donwsmith at gmail.com> wrote:
> > > Hi all,
> > >
> > > I'm trying to build an app using MultiService. I need to have 2
> > services,
> > > one that listens for UDP datagrams and another that can send those
> > datagrams
> > > to an ActiveMQ server via a Stomp client.
> > >
> > > I can set up the two services just fine, but I'm stuck with how to
> > call the
> > > MQ service send method from the UDPServer instance.
> > >
> > > Some code to illustrate:
> > >
> > >
> > >
> > > class GetUDP(DatagramProtocol):
> > >
> > >     def datagramReceived(self, datagram, address):
> > >         print datagram,address
> > >         #Send datagram to the queue server
> > >         # I don't know how to access the send method for the Stomp
> > client
> > > service!
> > >
> > >
> > >
> > > testq = internet.TCPClient(APPVARIABLES['queue_server'],
> > > int(APPVARIABLES['queue_port']), connections.StompClientFactory
> > > (username='',password='',queue='/queue/test'))
> > > testq.setName('Testq')
> > > testq.setServiceParent(MQService)
> > >
> > >
> > > #create a UDP listener
> > > #TODO: this should be driven by the config file
> > > #reactor.listenUDP(42000, GetUDP())
> > > internet.UDPServer(42000,GetUDP()).setServiceParent(MQService)
> > > # Create an application as normal
> > > application = service.Application("MQExample")
> > >
> > > # Connect our MultiService to the application, just like a normal
> > service.
> > > MQService.setServiceParent(application)
> > >
> > >
> > > Note: this is won't run exactly as is, but should give an idea of my
> > > problem. I've setup the ActiveMQ Stomp client as 'testq'. I've setup
> > the
> > > UDPServer service to listen for UDP packets. I can get the UDP packets
> > and
> > > print them, but I can't figure out how to hand them to my Stomp
> > client's
> > > send() method. This is possible, right?
> > >
> > > Thanks,
> > >
> > > Don
> > >
> > > _______________________________________________
> > > Twisted-Python mailing list
> > > Twisted-Python at twistedmatrix.com
> > > http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
> > >
> >
> > The answer is really easy -- you don't need any twisted magic to do
> > this, you just need to use standard Python mechanisms.  Your UDP
> > listener, when it receives some data, just needs a Python reference to
> > your Stomp client. You could have stuffed a reference to the Stomp
> > client in a module global variable (naughty!), or better, you could
> > have stuffed it in an attribute of your GetUDP object. So you could
> > change this line:
> >
> >   internet.UDPServer(42000,GetUDP()).setServiceParent(MQService)
> >
> > to these lines:
> >
> >   udpService = GetUDP()
> >   udpService.stompClient = testq  # stuff it in!
> >   internet.UDPServer(42000,udpService).setServiceParent(MQService)
> >
> > Cheers,
> > Christian
> >
> > _______________________________________________
> > Twisted-Python mailing list
> > Twisted-Python at twistedmatrix.com
> > http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
> >
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: </pipermail/twisted-python/attachments/20071212/e4c20667/attachment.html>


More information about the Twisted-Python mailing list