reconnect an asyncio ApplicationSession on connection/router drop

465 views
Skip to first unread message

Jonathan Moss

unread,
Jan 2, 2015, 12:08:10 AM1/2/15
to autob...@googlegroups.com
Hi All,

I am writing a component with autobahn.asyncio.wamp.ApplicationSession that is run with the ApplicationRunner connecting to an external instance of a crossbar.io router.

How am I able to:

1) Detect if the crossbar router drops out (onClose, onDisconnect, and onLeave do not appear to be called)?
2) Attempt to reconnect with that router?


I am happy implementing incremental back-offs for the reconnect and throwing out nasty error messages if it times out completely but I cannot seem to work out the 2 questions above.

autobahn==0.9.4-2 (running under cpython 3)
crossbar==0.9.12-2 (running under cpython 2.7.6)

Thanks,
Jon

Tobias Oberstein

unread,
Jan 3, 2015, 1:26:16 PM1/3/15
to autob...@googlegroups.com
Hi Jon,

regarding session lifecycle events, using this test component

=====

from autobahn.asyncio.wamp import ApplicationSession, ApplicationRunner

class MyComponent(ApplicationSession):

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

def onJoin(self, details):
print("session joined")

def onLeave(self, details):
print("session left")

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

if __name__ == '__main__':
runner = ApplicationRunner(url = "ws://localhost:8080/ws", realm =
"realm1")
runner.run(MyComponent)

=====

demonstrates that the repsective events fire : pls see attached screenshots.

Now, automatic reconnection should be implemented within ApplicationRunner:

https://github.com/tavendo/AutobahnPython/issues/295

Cheers,
/Tobias
> --
> 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/02e0d02e-2090-45d4-b244-eb6ad63a27ad%40googlegroups.com
> <https://groups.google.com/d/msgid/autobahnws/02e0d02e-2090-45d4-b244-eb6ad63a27ad%40googlegroups.com?utm_medium=email&utm_source=footer>.
> For more options, visit https://groups.google.com/d/optout.

wamp_session_lifecycle1.png
wamp_session_lifecycle2.png

Tobias Oberstein

unread,
Jan 3, 2015, 1:33:24 PM1/3/15
to autob...@googlegroups.com
Jon,

forgot 1 thing: I tested with Crossbar.io running locally. If your
client connects from remote (e.g. over the public Internet), and the
router gets lost, this is might not might immediately recognized by the
client - unless the client sends something.

This is TCP. To detect a dead TCP, you need (try) to send something.

Now, AutobahnPython has automatic WebSocket ping/pong with configurable
parameters and timeouts etc.

Crossbar.io has knobs to activate that : look in the docs under
WebSocket Options.

But that only covers Crossbar.io quickly detecting lost clients, not the
other direction.

Hence the option would need to be activated witin ApplicationRunner also ..

/Tobias

Jonathan Moss

unread,
Jan 3, 2015, 11:10:47 PM1/3/15
to autob...@googlegroups.com
Thanks Tobias,

This would be precisely the situation. The component would be running in a separate docker container than the router. So yes, I would need to implement a ping pong type feature.

I did indeed try this by registering a ping rpc method on the component. Then in the onJoin method of the same component, a while loop would call the ping method and detect when the connections disappears. 

I just couldn't work out how to attempt the reconnection with within the component. How would I do this, or would I actually need to perform the reconnect within the application runner?

Thanks again,
Jon

Tobias Oberstein

unread,
Jan 5, 2015, 5:38:19 AM1/5/15
to autob...@googlegroups.com
Hi Jon,

Am 04.01.2015 um 05:10 schrieb Jonathan Moss:
> Thanks Tobias,
>
> This would be precisely the situation. The component would be running in
> a separate docker container than the router. So yes, I would need to
> implement a ping pong type feature.

I'd try that first. When both processes are on the same machine or LAN,
TCP might be able to detect connection loss immediately - even without
ping/pong.

You also need to be careful _how_ you test: e.g. CTRL-C'ing Crossbar.io
is _not_ enough_ to test, since the former will orderly shutdown
Crossbar.io, and Twisted/OS will take care to properly close TCPs. You
need to "kill -9" Crossbar.io to test.

The ultimate test is this: use a browser with JS/WAMP on a mobile device
connecting to Crossbar.io over mobile carrier network (3G etc) and then
"kill -9" Crossbar.io. What you want is that the client quickly detects
the conneciton loss.

>
> I did indeed try this by registering a ping rpc method on the component.
> Then in the onJoin method of the same component, a while loop would call
> the ping method and detect when the connections disappears.

In general, ping/pong for connection keep-alive and fast connection-loss
detection should better be done at the WAMP transport level, not
application level (using WAMP RPC or such).

We have it for WebSocket, since ping/pong is built into WebSocket. But
only for CB->client. As far as I know, only IE does actively ping/pong
on WebSocket connections.

We have it for RawSocket transports (after the last revision of
RawSocket transport for WAMP), though that last revision is not yet
implemented in Crossbar.io.

For WAMP Longpoll transports it doesn't make sense.

>
> I just couldn't work out how to attempt the reconnection with within the
> component. How would I do this, or would I actually need to perform the
> reconnect within the application runner?

Yes.

Automatic reconnection must be implemented within ApplicationRunner.
There is an issue for that I think.

Cheers,
/Tobias

>
> Thanks again,
> Jon
>
>
>
> On Sunday, 4 January 2015 05:33:24 UTC+11, Tobias Oberstein wrote:
>
> Jon,
>
> forgot 1 thing: I tested with Crossbar.io running locally. If your
> client connects from remote (e.g. over the public Internet), and the
> router gets lost, this is might not might immediately recognized by the
> client - unless the client sends something.
>
> This is TCP. To detect a dead TCP, you need (try) to send something.
>
> Now, AutobahnPython has automatic WebSocket ping/pong with configurable
> parameters and timeouts etc.
>
> Crossbar.io has knobs to activate that : look in the docs under
> WebSocket Options.
>
> But that only covers Crossbar.io quickly detecting lost clients, not
> the
> other direction.
>
> Hence the option would need to be activated witin ApplicationRunner
> also ..
>
> /Tobias
>
> --
> 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/38353557-0c9d-4fd7-83ea-38e99357d5fb%40googlegroups.com
> <https://groups.google.com/d/msgid/autobahnws/38353557-0c9d-4fd7-83ea-38e99357d5fb%40googlegroups.com?utm_medium=email&utm_source=footer>.
Reply all
Reply to author
Forward
0 new messages