Периодическое выполнение функции по витому протоколу - PullRequest
24 голосов
/ 25 ноября 2008

Я ищу способ периодически отправлять некоторые данные по всем клиентам, подключенным к порту TCP. Я смотрю на витой питон, и я знаю о реакторе.callLater. Но как мне использовать его для периодической отправки данных всем подключенным клиентам? Логика отправки данных относится к классу протокола, и он создается реактором по мере необходимости. Я не знаю, как привязать его от реактора ко всем экземплярам протокола ...

Ответы [ 2 ]

38 голосов
/ 25 ноября 2008

Возможно, вы захотите сделать это на фабрике для соединений. Фабрика не получает автоматическое уведомление каждый раз, когда соединение установлено и потеряно, поэтому вы можете уведомить об этом из протокола.

Вот полный пример того, как использовать twisted.internet.task.LoopingCall в сочетании с настроенными базовыми фабрикой и протоколом, чтобы объявить, что «10 секунд прошло» для каждого соединения каждые 10 секунд.

from twisted.internet import reactor, protocol, task

class MyProtocol(protocol.Protocol):
    def connectionMade(self):
        self.factory.clientConnectionMade(self)
    def connectionLost(self, reason):
        self.factory.clientConnectionLost(self)

class MyFactory(protocol.Factory):
    protocol = MyProtocol
    def __init__(self):
        self.clients = []
        self.lc = task.LoopingCall(self.announce)
        self.lc.start(10)

    def announce(self):
        for client in self.clients:
            client.transport.write("10 seconds has passed\n")

    def clientConnectionMade(self, client):
        self.clients.append(client)

    def clientConnectionLost(self, client):
        self.clients.remove(client)

myfactory = MyFactory()
reactor.listenTCP(9000, myfactory)
reactor.run()
3 голосов
/ 25 ноября 2008

Я полагаю, что самый простой способ сделать это - управлять списком клиентов в протоколе с помощью connectionMade и connectionLost в клиенте, а затем использовать LoopingCall для запроса каждого клиента на отправку данных.

Это кажется немного инвазивным, но я не думаю, что вы захотите сделать это без протокола, имеющего некоторый контроль над передачей / приемом. Конечно, мне нужно увидеть ваш код, чтобы действительно знать, как он вписывается. Есть ссылка на GitHub? :)

...