Автобан + витое переподключение

У меня есть ряд клиентов, которые должны быть постоянно подключены к моему серверу через ws протокол. По ряду разных причин соединения иногда теряются. Это приемлемо, но когда это произойдет, я бы хотел, чтобы мои клиенты восстановили соединение.

В настоящее время мой временный обходной путь состоит в том, чтобы родительский процесс запустил клиент и, когда он обнаружил разрыв соединения, завершил его (клиент никогда не обрабатывает какие-либо критические данные, побочные эффекты отсутствуют). sigkillи возродим нового клиента. Хотя это и делает свою работу, я бы предпочел исправить проблему.

Это примерно мой клиент:

from autobahn.twisted.websocket import WebSocketClientProtocol, WebSocketClientFactory
from twisted.internet import reactor
from threading import Thread
from time import sleep


class Client:
    def __init__(self):
        self._kill = False

        self.factory = WebSocketClientFactory("ws://0.0.0.0")
        self.factory.openHandshakeTimeout = 60  # ensures handshake doesnt timeout due to technical limitations
        self.factory.protocol = self._protocol_factory()

        self._conn = reactor.connectTCP("0.0.0.0", 1234, self.factory)
        reactor.run()

    def _protocol_factory(self):
        class ClientProtocol(WebSocketClientProtocol):
            def onConnect(self, response):
                Thread(target=_self.mainloop, daemon=True).start()

            def onClose(self, was_clean, code, reason):
                _self.on_cleanup()

        _self = self
        return ClientProtocol

    def on_cleanup(self):
        self._kill = True
        sleep(30)
        # Wait for self.mainloop to finish. 
        # It is guaranteed to exit within 30 seconds of setting _kill flag
        self._kill = False
        self._conn = reactor.connectTCP("0.0.0.0", 1234, self.factory)

    def mainloop(self):
        while not self._kill:
            sleep(1)  # does some work

Этот код заставляет клиента работать правильно, пока первое соединение не прервется, и в этот момент он попытается восстановить соединение. Никаких исключений не возникает в процессе, кажется, что все прошло правильно на стороне клиента, onConnect называется и новый mainloop запускается, но сервер так и не получил это второе рукопожатие. Клиент, кажется, думает, что это связано, хотя.

Что я делаю неправильно? Почему это может происходить?

1 ответ

Я не извращенный эксперт и не могу точно сказать, что вы делаете неправильно, но в настоящее время я работаю с Autobahn в проекте, и я решил проблемы переподключения с помощью ReconnectingClientFactory. Может быть, вы хотите проверить некоторые примеры использования ReconnectingClientFactory с Autobahn.

Другие вопросы по тегам