How do I cleanly stop a WAMP Client

Hi there,

I’m working with a simple test WAMPClient class that is connecting to crossbar. I think it came from a demo I found somewhere in git on on the crossbar site. This client works, but does not return and can only be stopped with a CTRL-C and not programmatically. Picture that this client is running behind a QT5 GUI and must be stopped cleanly when the window close is clicked. Can anyone give some advice or insights how I would close this client cleanly? Does it involve saving the reference to the connection and then calling connection.close()?

Thank you. Here is my current client code:

#!/usr/bin/env python3
from autobahn.twisted.component import run
from autobahn.wamp.types import RegisterOptions
from autobahn.twisted.component import Component
from twisted.internet import reactor, task
from twisted.internet.defer import inlineCallbacks

class WAMPClient:

def __init__(self, url, realm):
    self._url = url
    self._realm = realm
    self._session = None

def run(self):
    self._connection = Component(
        transports=[{'url': self._url, 'type': 'websocket'}],
        realm=self._realm,
        authentication = {
                         "wampcra": {
                             'authid': 'testuser',
                             'secret': 'testpass',
                         }
                     }
    )
    self._connection.on('join', self.on_join)
    self._connection.on('leave', self.on_leave)
    run([self._connection])

def on_join(self, session, details=None):
    print("JOINED")
    self._session = session
    options = RegisterOptions(details_arg='details')

def on_leave(self, session, details=None):
    print("LEFT")

if name == ‘main’:
WAMPClient(‘ws://127.0.0.1:9000/ws’, ‘tactical’).run()

Hi there!

so the clean way to close a connection is by leaving the session by calling session.leave.

the default implementation of on_leave will then close the underlying transport connection.

if no auto-reconnect is in place, at this point everything related to the session and connection will be closed and cleaned up.

Hope this helps,
/Tobias

Sorry I should have been more specific. I need to start Twisted to run qt5 and get the user/password. Then after that point I need to start the session with that user/password. But when I execute run() to start the session it is blocking the main thread. Then it complains about having a nested reactor and connects again.

Is it possible to do what I need to do using only the main thread, or do I need to execute run() in a background thread?

Sorry I should have been more specific. I need to start Twisted to run qt5 and get the user/password. Then after that point I need to start the session with that user/password. But when I execute run() to start the session it is blocking the main thread. Then it complains about having a nested reactor and connects again.

Is it possible to do what I need to do using only the main thread, or do I need to execute run() in a background thread?

I had forgotten that I opened this dialog awhile ago. I am following it up now. You told me to use ApplicationSession in a previous thread (older thread), But I have read in the documentation and it seems to indicate .run() is better than a subclass:

You can use the same “component” APIs to run a component based on subclassing ApplicationSession. In older code it’s common to see autobahn.twisted.wamp.ApplicationRunner or autobahn.asyncio.wamp.ApplicationRunner. This runner lacks many of the options of the autobahn.twisted.component.run() or autobahn.asyncio.component.run() functions, so although it can still be useful you likely want to upgrade to run().

So so I want to use ApplicationSession here?

Ok so I just found out if I use the run() method, but call self._connection.start(reactor) instead of run([self._connection]) it seems to work properly and doesn’t re-run the start command and complain about nested reactors. Could have sworn I had tried this before but it’s working now.

Can you confirm that this is what I should be doing? Thank you.

Also, how do I stop retries after an auth error? It keeps retrying login with a bad auth and cannot be stopped with session.finish() or connection.stop()