Re: Client reconnecting from Websockets in Python

2,096 views
Skip to first unread message

Tobias Oberstein

unread,
Jun 20, 2013, 2:43:33 PM6/20/13
to autob...@googlegroups.com, Kevin Campion
Am 20.06.2013 16:35, schrieb Kevin Campion:
> Hi,
>
> I am trying to get Autobahn.Python to work with disconnecting when
> server down, without having to restart the program. The client program
> must try to reconnect every x seconds to the server.
>
> My source code works but when client reconnects, I can see in server's
> log multiple connection for the same client. I have an
> additional connection per trying reconnection.
>
> I think, it's when I use "connector.connect()"

Yep, sounds a bit like you are piling up new clients which each tries
to reconnect again and again.

Probably instead of implementing a reconnection policy yourself (yes, we
are guilty of that also), we should use

http://twistedmatrix.com/documents/current/api/twisted.internet.protocol.ReconnectingClientFactory.html
http://twistedmatrix.com/documents/13.0.0/core/howto/clients.html

The "problem" is, Autobahn (currently) defines


class WebSocketClientFactory(protocol.ClientFactory, WebSocketFactory):
"""
A Twisted factory for WebSocket client protocols.
"""

protocol = WebSocketClientProtocol

==

Probably this works:

class MyFactory(ReconnectingClientFactory, WebSocketClientFactory)

Not sure, cannot test right now.

Possibly, the empty implementation in
WebSocketClientFactory.clientConnectionFailed and clientConnectionLost
are "in the way" ..

Anyway, I'd try to either use ReconnectingClientFactory or have a look
at the implementation.

/Tobias


>
> I use this discussion and the example on GitHub :
> https://groups.google.com/forum/?fromgroups#!searchin/autobahnws/reconnect|sort:relevance/autobahnws/HCNFWKGYQCM/G1EGNGxOZXkJ
> https://github.com/tavendo/AutobahnTestSuite/blob/master/autobahntestsuite/autobahntestsuite/testee.py#L87
> <https://github.com/tavendo/AutobahnTestSuite/blob/master/autobahntestsuite/autobahntestsuite/testee.py#L87>
>
>
> My TesteeClientFactory class looks like this :
>
> class TesteeClientFactory(WebSocketClientFactory):
> protocol = TesteeClientProtocol
> def clientConnectionLost(self, connector, reason):
> connector.connect()
>
> def clientConnectionFailed(self, connector, reason):
> print "Connection to %s failed (%s)" % (self.url,
> reason.getErrorMessage())
> self.tryToConnect(connector)
> def tryToConnect(self, connector):
> connector.disconnect()
> var = 1
> while var == 1 :
> time.sleep( 2 )
> newConnection = connector.connect()
> if newConnection != None:
> break
> connector.disconnect()
>
> --
> 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.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

Tobias Oberstein

unread,
Jun 20, 2013, 2:54:58 PM6/20/13
to autob...@googlegroups.com, Kevin Campion

Kevin Campion

unread,
Jun 21, 2013, 6:14:35 AM6/21/13
to autob...@googlegroups.com, Kevin Campion
Well, I found the solution thanks to you.

1) When you use the source code with "connector.connect()" on "clientConnectionLost" and "clientConnectionFailed", like my previous email; if server is down, the client will try to reconnect every time as he can (3 times per second or more)

2) When you use the source code with "ReconnectingClientFactory"; if server is down, the client will try to reconnect and if he failed, he tries after 2 secondes, and after 6 seconds, and after 8 seconds... until 3600 seconds (by default)

Look my example, I block the max delay to 10 seconds :

class TesteeClientFactory(ReconnectingClientFactory, WebSocketClientFactory):

    protocol = TesteeClientProtocol

    def startedConnecting(self, connector):
        print 'Started to connect.'

    def buildProtocol(self, addr):
        print 'Connected.'
        
        self.maxDelay = 10

        return WebSocketClientFactory.buildProtocol(self, addr)

    def clientConnectionLost(self, connector, reason):
        print 'Lost connection.  Reason:', reason
        ReconnectingClientFactory.clientConnectionLost(self, connector, reason)

    def clientConnectionFailed(self, connector, reason):
        print 'Connection failed. Reason:', reason
        ReconnectingClientFactory.clientConnectionFailed(self, connector,
                                                         reason)


Thank you for your help.

Tobias Oberstein

unread,
Jun 22, 2013, 5:49:12 AM6/22/13
to autob...@googlegroups.com, Kevin Campion
Hi Kevin,

yes, the ReconnectingClientFactory code does (jitter'ed) exponential
backoff.

I've added an example to the repo:

https://github.com/tavendo/AutobahnPython/blob/master/examples/websocket/echo/client_reconnecting.py

/Tobias

Am 21.06.2013 12:14, schrieb Kevin Campion:
> Well, I found the solution thanks to you.
>
> 1) When you use the source code with "connector.connect()" on
> "clientConnectionLost" and "clientConnectionFailed", like my previous
> email; if server is down, the client will try to reconnect every time as
> he can (3 times per second or more)
>
> 2) When you use the source code with "ReconnectingClientFactory"; if
> server is down, the client will try to reconnect and if he failed, he
> tries after 2 secondes, and after 6 seconds, and after 8 seconds...
> until 3600 <tel:3600> seconds (by default)
>
> Look my example, I block the max delay to 10 seconds :
>
> class TesteeClientFactory(ReconnectingClientFactory,
> WebSocketClientFactory):
>
> protocol = TesteeClientProtocol
>
> def startedConnecting(self, connector):
> print 'Started to connect.'
>
> def buildProtocol(self, addr):
> print 'Connected.'
> self.maxDelay = 10
>
> return WebSocketClientFactory.buildProtocol(self, addr)
>
> def clientConnectionLost(self, connector, reason):
> print 'Lost connection. Reason:', reason
> ReconnectingClientFactory.clientConnectionLost(self, connector,
> reason)
>
> def clientConnectionFailed(self, connector, reason):
> print 'Connection failed. Reason:', reason
> ReconnectingClientFactory.clientConnectionFailed(self, connector,
> reason)
>
>
> Thank you for your help.
>

Kevin Campion

unread,
Jun 24, 2013, 10:51:22 AM6/24/13
to autob...@googlegroups.com, Kevin Campion
Thank you

Ash Clarke

unread,
Mar 9, 2014, 7:49:27 PM3/9/14
to autob...@googlegroups.com, Kevin Campion

James Firth

unread,
Sep 11, 2015, 1:43:24 PM9/11/15
to Autobahn, campio...@gmail.com
Hi I was looking at the new example and apparently mis-understand something.

I was told to use "ReconnectingClientFactory.resetDelay()" after the connection has completed due to the reconnect back-off.

if I place that line in MyClientProtocol.onConnect I get a loop of connection losses/reconnect attempts.

If I place it in MyClientProtocol.onOpen I get an error that I need an instance of ReconnectingClientFactory.

Where is the proper place to put "ReconnectingClientFactory.resetDelay()"?

Thanks!

meejah

unread,
Sep 24, 2015, 11:17:14 AM9/24/15
to Autobahn, campio...@gmail.com


On Friday, 11 September 2015 11:43:24 UTC-6, James Firth wrote:
 
Where is the proper place to put "ReconnectingClientFactory.resetDelay()"?

 
Hi James,

This works for me:  https://github.com/tavendo/AutobahnPython/pull/522/files

--
meejah

James Firth

unread,
Oct 2, 2015, 1:19:41 PM10/2/15
to Autobahn, campio...@gmail.com
This appears to have helped a lot, thanks!
Reply all
Reply to author
Forward
0 new messages