Detecting websocket close in WAMP ApplicationSession

432 views
Skip to first unread message

Joseph Schorr

unread,
Oct 27, 2014, 1:02:02 PM10/27/14
to autob...@googlegroups.com
Apologies if this is an obvious question :)

I have a simple Python ApplicationSession implemented like so:

class MySession(ApplicationSession):
  def onConnect(self):   
    self.join("my-realm")

  def onClose(self, details):
    print 'Close'

  def onLeave(self, details):
    print 'Leave'

  @trollius.coroutine
  def onJoin(self, details):
     # RPC methods exported here


Occasionally, the client calling this session will have its connection dropped, which results in the following error being raised:

WAMP-over-WebSocket transport lost: wasClean = False, code = 1006, reason = 'connection was closed uncleanly (peer dropped the TCP connection without previous WebSocket closing handshake)'


This is all fine and expected, but the onClose and/or onLeave methods on the session are not being called. Is there a way to detect in the session when the underlying websocket has failed or closed?

Thanks!
Joseph Schorr

redabo...@gmail.com

unread,
Oct 27, 2014, 5:47:44 PM10/27/14
to autob...@googlegroups.com
Try subscribing to the "wamp.metaevents" in case you haven't tried that already. In Nodejs, I did it like this and they never fail me:

        session.subscribe('wamp.metaevent.session.on_join', on_event_join).then(
            function(subscription){
                console.log('Subscription succeeded', subscription.topic);
            },
            function(error){
                console.log('Subscription failed', error);
            }
        );       
       
        session.subscribe('wamp.metaevent.session.on_leave', on_event_leave).then(
            function(subscription){
                console.log('Subscription succeeded', subscription.topic);
            },
            function(error){
                console.log('Subscription failed', error);
            }
        );       
    };

Joseph Schorr

unread,
Oct 27, 2014, 5:51:34 PM10/27/14
to autob...@googlegroups.com
Add the following didn't seem to work, unfortunately :-/

    def on_disconnect():
      print "DISCONNECTED"

   yield self.subscribe(on_disconnect, 'wamp.metaevent.session.on_leave')

redabo...@gmail.com

unread,
Oct 27, 2014, 6:17:23 PM10/27/14
to autob...@googlegroups.com
Hi,

Just FYI, I am using crossbar.io. I am not sure if other wamp servers support this feature.

Rgds,
Reda

Tobias Oberstein

unread,
Oct 28, 2014, 6:42:03 PM10/28/14
to autob...@googlegroups.com
Hi Joseph,

> This is all fine and expected, but the onClose and/or onLeave methods on
> the session are not being called. Is there a way to detect in the
> session when the underlying websocket has failed or closed?

The following output is what I get when I kill the router process the
client (see code that follows) is connected to:

$ python test2.py
onConnect
onJoin: SessionDetails(realm = realm1, session = 5915234306773300,
authid = 5FlQx7hYoqdP1nJmhoGvb6Jf, authrole = anonymous, authmethod = ano
nymous)
onLeave: CloseDetails(reason = None, message = 'None'')
onDisconnect

===

from autobahn.asyncio.wamp import ApplicationSession

class MyComponent(ApplicationSession):

def onConnect(self):
print("onConnect")
self.join(self.config.realm)

def onJoin(self, details):
print("onJoin: {0}".format(details))

def onLeave(self, details):
print("onLeave: {0}".format(details))

def onDisconnect(self):
print("onDisconnect")


if __name__ == '__main__':
from autobahn.asyncio.wamp import ApplicationRunner

runner = ApplicationRunner(url = "ws://127.0.0.1:8080/ws", realm =
"realm1")
runner.run(MyComponent)


===

The lifecycle callbacks of a WAMP session are documented here:

http://autobahn.ws/python/reference/autobahn.wamp.html#autobahn.wamp.interfaces.ISession

===

The metaevents mentioned in the reply by Reda are for something slightly
different: when you want to monitor a _different_ session from disappearing.

Please let me know if above works for you (the lifecycle stuff) ..

Cheers,
/Tobias

>
> Thanks!
> Joseph Schorr
>
> --
> You received this message because you are subscribed to the Google
> Groups "Autobahn" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to autobahnws+...@googlegroups.com
> <mailto:autobahnws+...@googlegroups.com>.
> To post to this group, send email to autob...@googlegroups.com
> <mailto:autob...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/autobahnws/ee3fd1af-12e0-4d62-8133-5e647ba9a95c%40googlegroups.com
> <https://groups.google.com/d/msgid/autobahnws/ee3fd1af-12e0-4d62-8133-5e647ba9a95c%40googlegroups.com?utm_medium=email&utm_source=footer>.
> For more options, visit https://groups.google.com/d/optout.

Joseph Schorr

unread,
Oct 29, 2014, 3:54:44 PM10/29/14
to autob...@googlegroups.com
Hey Tobias,

Hmm, that might explain it. I was trying to setup a multi-realm server like so:

def run_local_server(ip, port):
  router_factory = RouterFactory()

  session_factory = RouterSessionFactory(router_factory)
  session_factory.add(MyComponent(types.ComponentConfig(realm = 'my-realm')))

  transport_factory = WampWebSocketServerFactory(session_factory, debug_wamp = True)
  transport_factory.setProtocolOptions(failByDrop = True)

  loop = trollius.get_event_loop()
  coro = loop.create_server(transport_factory, ip, port)
  server = loop.run_until_complete(coro)

  print 'Starting server on port %s' % port
  try:
     ## now enter the asyncio event loop
     loop.run_forever()
  except KeyboardInterrupt:
     pass
  finally:
     server.close()
     loop.close()


Is the application runner the better choice and does it support registering additional component+realms dynamically?

Thanks,
Joseph Schorr


To post to this group, send email to autob...@googlegroups.com

--
You received this message because you are subscribed to a topic in the Google Groups "Autobahn" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/autobahnws/HaIWAe-pylk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to autobahnws+unsubscribe@googlegroups.com.
To post to this group, send email to autob...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/autobahnws/54501BB4.70000%40gmail.com.

Joseph Schorr

unread,
Oct 30, 2014, 4:09:11 PM10/30/14
to autob...@googlegroups.com
Hey Tobias,

So I think the problem is that the router in between the server and the session is not forwarding the onClose/onLeave calls. Is there a way to have a multi-realm server without the router?

Sorry for all the questions, but the system is quite complex :)

Thanks,
Joseph Schorr

Tobias Oberstein

unread,
Oct 30, 2014, 7:33:58 PM10/30/14
to autob...@googlegroups.com
ApplicationRunner is a few lines of code that wraps some boilerplate:

https://github.com/tavendo/AutobahnPython/blob/master/autobahn/autobahn/twisted/wamp.py#L205

If you run it "standalone", it will also start a router, but different
from what you did above, it doesn't run the app component embedded
(session_factory.add(MyComponent()), but lets the component connect to
the router over loopback TCP.

> registering additional component+realms dynamically?

Realms: yes. Since the basic router included with AutobahnPython (which
ApplicationRunner uses when running standalone == True), simply will
create a new realm when the first client for that realm connects.

Components: no. ApplicationRunner does not provide that.


>
> Thanks,
> Joseph Schorr
>
> On Tue, Oct 28, 2014 at 6:41 PM, Tobias Oberstein
> <tobias.o...@gmail.com <mailto:tobias.o...@gmail.com>> wrote:
>
> Hi Joseph,
>
> This is all fine and expected, but the onClose and/or onLeave
> methods on
> the session are not being called. Is there a way to detect in the
> session when the underlying websocket has failed or closed?
>
>
> The following output is what I get when I kill the router process
> the client (see code that follows) is connected to:
>
> $ python test2.py
> onConnect
> onJoin: SessionDetails(realm = realm1, session = 5915234306773300,
> authid = 5FlQx7hYoqdP1nJmhoGvb6Jf, authrole = anonymous, authmethod
> = ano
> nymous)
> onLeave: CloseDetails(reason = None, message = 'None'')
> onDisconnect
>
> ===
>
> from autobahn.asyncio.wamp import ApplicationSession
>
> class MyComponent(__ApplicationSession):
>
> def onConnect(self):
> print("onConnect")
> self.join(self.config.realm)
>
> def onJoin(self, details):
> print("onJoin: {0}".format(details))
>
> def onLeave(self, details):
> print("onLeave: {0}".format(details))
>
> def onDisconnect(self):
> print("onDisconnect")
>
>
> if __name__ == '__main__':
> from autobahn.asyncio.wamp import ApplicationRunner
>
> runner = ApplicationRunner(url = "ws://127.0.0.1:8080/ws
> <http://127.0.0.1:8080/ws>", realm = "realm1")
> runner.run(MyComponent)
>
>
> ===
>
> The lifecycle callbacks of a WAMP session are documented here:
>
> http://autobahn.ws/python/__reference/autobahn.wamp.html#__autobahn.wamp.interfaces.__ISession
> <http://autobahn.ws/python/reference/autobahn.wamp.html#autobahn.wamp.interfaces.ISession>
>
> ===
>
> The metaevents mentioned in the reply by Reda are for something
> slightly different: when you want to monitor a _different_ session
> from disappearing.
>
> Please let me know if above works for you (the lifecycle stuff) ..
>
> Cheers,
> /Tobias
>
>
> Thanks!
> Joseph Schorr
>
> --
> You received this message because you are subscribed to the Google
> Groups "Autobahn" group.
> To unsubscribe from this group and stop receiving emails from
> it, send
> an email to autobahnws+unsubscribe@__googlegroups.com
> <mailto:autobahnws%2Bunsu...@googlegroups.com>
> <mailto:autobahnws+_...@googlegroups.com
> <mailto:autobahnws%2Bunsu...@googlegroups.com>>.
> To post to this group, send email to autob...@googlegroups.com
> <mailto:autob...@googlegroups.com>
> <mailto:autobahnws@__googlegroups.com
> <mailto:autob...@googlegroups.com>>.
> To view this discussion on the web visit
> https://groups.google.com/d/__msgid/autobahnws/ee3fd1af-__12e0-4d62-8133-5e647ba9a95c%__40googlegroups.com
> <https://groups.google.com/d/msgid/autobahnws/ee3fd1af-12e0-4d62-8133-5e647ba9a95c%40googlegroups.com>
> <https://groups.google.com/d/__msgid/autobahnws/ee3fd1af-__12e0-4d62-8133-5e647ba9a95c%__40googlegroups.com?utm_medium=__email&utm_source=footer
> <https://groups.google.com/d/msgid/autobahnws/ee3fd1af-12e0-4d62-8133-5e647ba9a95c%40googlegroups.com?utm_medium=email&utm_source=footer>>.
> For more options, visit https://groups.google.com/d/__optout
> <https://groups.google.com/d/optout>.
>
>
> --
> You received this message because you are subscribed to a topic in
> the Google Groups "Autobahn" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/__topic/autobahnws/HaIWAe-pylk/__unsubscribe
> <https://groups.google.com/d/topic/autobahnws/HaIWAe-pylk/unsubscribe>.
> To unsubscribe from this group and all its topics, send an email to
> autobahnws+unsubscribe@__googlegroups.com
> <mailto:autobahnws%2Bunsu...@googlegroups.com>.
> To post to this group, send email to autob...@googlegroups.com
> <mailto:autob...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/__msgid/autobahnws/54501BB4.__70000%40gmail.com
> <https://groups.google.com/d/msgid/autobahnws/54501BB4.70000%40gmail.com>.
>
> For more options, visit https://groups.google.com/d/__optout
> <https://groups.google.com/d/optout>.
>
>
> --
> You received this message because you are subscribed to the Google
> Groups "Autobahn" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to autobahnws+...@googlegroups.com
> <mailto:autobahnws+...@googlegroups.com>.
> To post to this group, send email to autob...@googlegroups.com
> <mailto:autob...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/autobahnws/CAL9hb3g9xvoxUSwQCORhtZa_rCioeAM1v7%2BycK7sPw57hSbTpg%40mail.gmail.com
> <https://groups.google.com/d/msgid/autobahnws/CAL9hb3g9xvoxUSwQCORhtZa_rCioeAM1v7%2BycK7sPw57hSbTpg%40mail.gmail.com?utm_medium=email&utm_source=footer>.

Tobias Oberstein

unread,
Oct 30, 2014, 7:40:34 PM10/30/14
to autob...@googlegroups.com
Hi Joseph,

Am 30.10.2014 21:09, schrieb Joseph Schorr:
> Hey Tobias,
>
> So I think the problem is that the router in between the server and the
> session is not forwarding the onClose/onLeave calls. Is there a way to
> have a multi-realm server without the router?

Every WAMP based application needs a router. This is the part that lets
app components talk to each other.

A single router can manage many realms.

Whether a router is "a server" depends on whether the router is actually
accepting network connections.

E.g. you can create a WAMP app with a router and all app components
running embedded in the router, and the router not listening on any
network ports at all. In this case I wouldn't call the router "a
server". Essentially, the router in this case only acts internally for
the app, and allows the app to be composed of components, but the
components are not exposed or accesible from outside.

>
> Sorry for all the questions, but the system is quite complex :)

No problem at all - keep on asking;) I am also learning each time ..
what's hard to understand, what people actually want to do, etc.

Cheers,
/Tobias
> class MyComponent(__ApplicationSession):
>
> def onConnect(self):
> print("onConnect")
> self.join(self.config.realm)
>
> def onJoin(self, details):
> print("onJoin: {0}".format(details))
>
> def onLeave(self, details):
> print("onLeave: {0}".format(details))
>
> def onDisconnect(self):
> print("onDisconnect")
>
>
> if __name__ == '__main__':
> from autobahn.asyncio.wamp import ApplicationRunner
>
> runner = ApplicationRunner(url = "ws://127.0.0.1:8080/ws
> <http://127.0.0.1:8080/ws>", realm = "realm1")
> runner.run(MyComponent)
>
>
> ===
>
> The lifecycle callbacks of a WAMP session are documented here:
>
> http://autobahn.ws/python/__reference/autobahn.wamp.html#__autobahn.wamp.interfaces.__ISession
> <http://autobahn.ws/python/reference/autobahn.wamp.html#autobahn.wamp.interfaces.ISession>
>
> ===
>
> The metaevents mentioned in the reply by Reda are for something
> slightly different: when you want to monitor a _different_
> session from disappearing.
>
> Please let me know if above works for you (the lifecycle stuff) ..
>
> Cheers,
> /Tobias
>
>
> Thanks!
> Joseph Schorr
>
> --
> You received this message because you are subscribed to the
> Google
> Groups "Autobahn" group.
> To unsubscribe from this group and stop receiving emails
> from it, send
> an email to autobahnws+unsubscribe@__googlegroups.com
> <mailto:autobahnws%2Bunsu...@googlegroups.com>
> <mailto:autobahnws+_...@googlegroups.com
> <mailto:autobahnws%2Bunsu...@googlegroups.com>>.
> To post to this group, send email to
> <mailto:autob...@googlegroups.com>>.
> To view this discussion on the web visit
> <https://groups.google.com/d/msgid/autobahnws/ee3fd1af-12e0-4d62-8133-5e647ba9a95c%40googlegroups.com?utm_medium=email&utm_source=footer>>.
> For more options, visit https://groups.google.com/d/__optout
> <https://groups.google.com/d/optout>.
>
>
> --
> You received this message because you are subscribed to a topic
> in the Google Groups "Autobahn" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/__topic/autobahnws/HaIWAe-pylk/__unsubscribe
> <https://groups.google.com/d/topic/autobahnws/HaIWAe-pylk/unsubscribe>.
> To unsubscribe from this group and all its topics, send an email
> to autobahnws+unsubscribe@__googlegroups.com
> <mailto:autobahnws%2Bunsu...@googlegroups.com>.
> To post to this group, send email to autob...@googlegroups.com
> <mailto:autob...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/__msgid/autobahnws/54501BB4.__70000%40gmail.com
> <https://groups.google.com/d/msgid/autobahnws/54501BB4.70000%40gmail.com>.
>
> For more options, visit https://groups.google.com/d/__optout
> <https://groups.google.com/d/optout>.
>
>
>
> --
> You received this message because you are subscribed to the Google
> Groups "Autobahn" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to autobahnws+...@googlegroups.com
> <mailto:autobahnws+...@googlegroups.com>.
> To post to this group, send email to autob...@googlegroups.com
> <mailto:autob...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/autobahnws/CAL9hb3ih7RAv67N2Kn8%3DCOhQw4X1PA6FYSe30SAza4_64N%3DMrw%40mail.gmail.com
> <https://groups.google.com/d/msgid/autobahnws/CAL9hb3ih7RAv67N2Kn8%3DCOhQw4X1PA6FYSe30SAza4_64N%3DMrw%40mail.gmail.com?utm_medium=email&utm_source=footer>.
Reply all
Reply to author
Forward
0 new messages