简体   繁体   中英

Reconnecting to a websocket using AutoBahn

I'm getting data from the Poloniex API by consuming their websocket API. I'm using the AutoBahn Python websocket library .

Currently, I'm using the following code to print ticket data as it becomes available. This works well, but not for extended periods of time. Every 12-36 hours it stops producing output (I think when Poloniex restart their servers).

Is there an elegant way to check if the ApplicationRunner is still connected, and to restart it if it disconnects? The onDisconnect is not triggering. When I run the script, the process does not terminate when the socket stops receiving data, so I don't think that the event loop gets stopped.

from autobahn.asyncio.wamp import ApplicationSession
from autobahn.asyncio.wamp import ApplicationRunner
from asyncio import coroutine
import asyncio
from datetime import datetime

class PoloniexComponent(ApplicationSession):
    def onConnect(self):
        self.join(self.config.realm)

    @coroutine
    def onJoin(self, details):
        def onTicker(*args):
            print("{}: {}".format(datetime.utcnow(), str(args)))
        try:
            yield from self.subscribe(onTicker, 'ticker')
        except Exception as e:
            print("Could not subscribe to topic:", e)

    def onDisconnect(self):
        asyncio.get_event_loop().stop()


def main():
    runner = ApplicationRunner("wss://api.poloniex.com:443", "realm1")
    runner.run(PoloniexComponent)

if __name__ == "__main__":
    main()

Since WebSocket connections are persistent, and no data is sent when there's no need, without actual traffic it's not discovered that the underlying connection has been killed (which is what happens when Poloniex Websocket server restart) - at least not quickly.

To enable reacting quickly and deterministically to the disconnect , it is required to enable WebSocket auto pings on server side. [ source ]

I don't know but suppose that polo have not activated this option ...

But you could build your "own" active ping version using something like this:

Create another ApplicationRunner instance (named "runner_watcher"), try to subscribe to a new topic with it and when it s done close the instance, then wait N second and restart the procedure, etc..

When the Exception ("Could not subscribe to topic") is raised on your "runner_watcher" instance, you may probably assume that server is down ..., so you force the stop of the primary ApplicationRunner and when server is back (no more Exception raised during execution of "runner_watcher", you may assume server is up again and restart the primary ApplicationRunner

I agree that this approach is dirty (not elegant), but it may probably works

Automatic reconnection was not yet implemented in autobahn in 2015 , but currently in the works.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM