Zdaję sobie sprawę, że prawdopodobnie jestem po prostu głupi i brakuje czegoś dużego i ważnego, ale nie mogę wymyślić, jak określić limit czasu w skręcanym przy użyciu reaktora.listenUDP. Moim celem jest możliwość określenia limitu czasu, a po wspomnianym czasie, jeśli DatagramProtocol.datagramReceived nie został wykonany, niech wywoła on wywołanie zwrotne lub coś, co mogę użyć do wywołania metody reactor.stop(). Każda pomoc lub porada jest doceniana. DziękiCzy jest możliwe ustawienie limitu czasu na gnieździe w Twisted?
8
A
Odpowiedz
5
Ponieważ Twisted jest napędzany zdarzeniami, nie potrzebujesz przerwy czasowej jako takiej. Wystarczy ustawić zmienną stanu (jak datagramRecieved) po odebraniu datagramu i zarejestrować looping call który sprawdza zmiennej stanu, zatrzymanie reaktora w razie potrzeby, a następnie czyści zmienny stan:
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()
13
myślę reactor.callLater
będzie działać lepiej niż LoopingCall
. Coś takiego:
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))
3
z reaktorem musimy użyć callLater. Rozpocznij odliczanie czasu oczekiwania, gdy connectionMade. Resetowanie odliczania czasu oczekiwania po wywołaniu linii.
Oto
# -*- 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
Lepszym sposobem zrobić to z twisted.protocols.policies.TimeoutMixin
. Zasadniczo robi się to w postaci callLater
, ale wyodrębnia się je w Mixin
.