2008-10-21 10 views
8

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?

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.

Powiązane problemy