2008-10-21 17 views
8

Ich realisiere, dass ich wahrscheinlich nur dumm bin und etwas Großes und Wichtiges vermisse, aber ich kann nicht herausfinden, wie man ein Timeout in twisted mit reactor.listenUDP spezifiziert. Mein Ziel ist es, in der Lage zu sein, eine Zeitüberschreitung festzulegen, und nach Ablauf dieser Zeit, wenn DatagramProtocol.datagramReceived nicht ausgeführt wurde, führe einen Callback oder etwas aus, das ich verwenden kann, um reactor.stop() aufzurufen. Jede Hilfe oder Beratung wird geschätzt. DankeKann in Twisted ein Timeout für einen Socket eingestellt werden?

Antwort

5

Da Twisted ereignisgesteuert ist, brauchen Sie kein Timeout per se. Sie müssen lediglich eine Zustandsvariablen setzen (wie datagramRecieved), wenn Sie ein Datagramm empfangen und ein looping call Register, das die Zustandsvariablen überprüft, stoppt den Reaktor falls dann Zustandsgröße löscht:

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

ich reactor.callLater denken würde besser funktionieren als LoopingCall. Etwas wie dieses:

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

mit Reaktor müssen wir callLater verwenden. Start-Countdown beim Verbindungsaufbau starten. Countdown für Zeitlimit zurücksetzen, wenn lineReceived.

Hier ist die

# -*- 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

Eine bessere Möglichkeit, dies mit twisted.protocols.policies.TimeoutMixin zu tun ist. Es ist im Wesentlichen eine aber abstrahiert in eine Mixin.