Можно ли установить таймаут для сокета в Twisted? - PullRequest
8 голосов
/ 21 октября 2008

Я понимаю, что, возможно, я просто тупой и упускаю что-то большое и важное, но я не могу понять, как указать таймаут в витой форме с использованием реактором.listenUDP. Моя цель состоит в том, чтобы иметь возможность указать тайм-аут, и после указанного промежутка времени, если DatagramProtocol.datagramReceived не был выполнен, он должен выполнить обратный вызов или что-то, что я могу использовать для вызова реактора. Любая помощь или совет приветствуется. Спасибо

Ответы [ 4 ]

13 голосов
/ 30 октября 2008

Я думаю reactor.callLater будет работать лучше, чем LoopingCall. Примерно так:

class Protocol(DatagramProtocol):
    def __init__(self, timeout):
        self.timeout = timeout

    def datagramReceived(self, datagram):
        self.timeout.cancel()
        # ...

timeout = reactor.callLater(5, timedOut)
reactor.listenUDP(Protocol(timeout))
5 голосов
/ 21 октября 2008

Поскольку Twisted управляется событиями, вам не нужен тайм-аут как таковой. Вам просто нужно установить переменную состояния (например, datagramRectained), когда вы получаете дейтаграмму и регистрируете циклический вызов , который проверяет переменную состояния, останавливает реактор, если необходимо, затем очищает переменную состояния:

from twisted.internet import task
from twisted.internet import reactor

datagramRecieved = False
timeout = 1.0 # One second

# UDP code here

def testTimeout():
    global datagramRecieved
    if not datagramRecieved:
        reactor.stop()
    datagramRecieved = False


l = task.LoopingCall(testTimeout)
l.start(timeout) # call every second

# l.stop() will stop the looping calls
reactor.run()
3 голосов
/ 04 августа 2012

с реактором мы должны использовать callLater. Начните отсчет времени ожидания, когда ConnectionMade. Сброс тайм-аута, когда lineReceived.

Вот вам

# -*- coding: utf-8 -*-

from twisted.internet.protocol import Factory
from twisted.protocols.basic import LineReceiver
from twisted.internet import reactor, defer

_timeout = 27


class ServiceProtocol(LineReceiver):

    def __init__(self, users):
        self.users = users


    def connectionLost(self, reason):
        if self.users.has_key(self.name):
            del self.users[self.name]

    def timeOut(self):
        if self.users.has_key(self.name):
            del self.users[self.name]
        self.sendLine("\nOUT: 9 - Disconnected, reason: %s" % 'Connection Timed out')
        print "%s - Client disconnected: %s. Reason: %s" % (datetime.now(), self.client_ip, 'Connection Timed out' )
        self.transport.loseConnection()

    def connectionMade(self):
        self.timeout = reactor.callLater(_timeout, self.timeOut)

        self.sendLine("\nOUT: 7 - Welcome to CAED")

    def lineReceived(self, line):
        # a simple timeout procrastination
        self.timeout.reset(_timeout)

class ServFactory(Factory):

    def __init__(self):
        self.users = {} # maps user names to Chat instances

    def buildProtocol(self, addr):
        return ServiceProtocol(self.users)

port = 8123
reactor.listenTCP(port, ServFactory())
print "Started service at port %d\n" % port
reactor.run()
0 голосов
/ 22 июля 2014

Лучший способ сделать это с twisted.protocols.policies.TimeoutMixin. По сути, он делает callLater, но абстрагируется в Mixin.

...