How to send Autobahn/Twisted WAMP message from outside of protocol?
Asked Answered
E

1

6

I am following the basic wamp pubsub examples in the github code:

This example publishes messages from within the class:

class Component(ApplicationSession):
   """
An application component that publishes an event every second.
"""

   def __init__(self, realm = "realm1"):
      ApplicationSession.__init__(self)
      self._realm = realm


   def onConnect(self):
      self.join(self._realm)


   @inlineCallbacks
   def onJoin(self, details):
      counter = 0
      while True:
         self.publish('com.myapp.topic1', counter)
         counter += 1
         yield sleep(1)

I want to create a reference so that I can publish messages over this connection from elsewhere in the code, i.e. myobject.myconnection.publish('com.myapp.topic1', 'My message')

From this similar question the answer seems to be that upon connection, I need to set something like self.factory.myconnection = self. I have tried multiple permutations of this without success.

The factory setup portion is below:

   ## create a WAMP application session factory
   ##
   from autobahn.twisted.wamp import ApplicationSessionFactory
   session_factory = ApplicationSessionFactory()


   ## .. and set the session class on the factory
   ##
   session_factory.session = Component


   ## create a WAMP-over-WebSocket transport client factory
   ##
   from autobahn.twisted.websocket import WampWebSocketClientFactory
   transport_factory = WampWebSocketClientFactory(session_factory, args.wsurl, debug = args.debug)
   transport_factory.setProtocolOptions(failByDrop = False)


   ## start a WebSocket client from an endpoint
   ##
   client = clientFromString(reactor, args.websocket)
   client.connect(transport_factory)

Where would any reference that I set from within the class be attached? to client? to transport_factory? to session_factory?

Emogeneemollient answered 21/3, 2014 at 3:4 Comment(0)
S
7

Upon your app session joining the WAMP realm, it sets a reference to itself on the app session factory:

class MyAppComponent(ApplicationSession):

   ... snip

   def onJoin(self, details):
      if not self.factory._myAppSession:
         self.factory._myAppSession = self

You then can access this session from elsewhere in your code, e.g.

   @inlineCallbacks
   def pub():
      counter = 0  
      while True:
         ## here we can access the app session that was created ..
         ##
         if session_factory._myAppSession:
            session_factory._myAppSession.publish('com.myapp.topic123', counter)
            print("published event", counter)
         else:
            print("no session")
         counter += 1
         yield sleep(1)

   pub()
Scleroderma answered 21/3, 2014 at 13:7 Comment(2)
Thanks for adding an "official" example. It turns out my main problem was that my program was trying to access the session reference before it was fully initialized.Emogeneemollient
Link is dead; example moved, or removed? I got as far as this looking for something like session/fromoutside before giving up.Bone

© 2022 - 2024 — McMap. All rights reserved.