2008-10-21 3 views
8

Je me rends compte que je suis probablement stupide et qu'il manque quelque chose de grand et d'important, mais je n'arrive pas à comprendre comment spécifier un timeout en twisted en utilisant reactor.listenUDP. Mon but est de pouvoir spécifier un timeout, et après ce laps de temps, si DatagramProtocol.datagramReceived n'a pas été exécuté, faites-lui exécuter un callback ou quelque chose que je peux utiliser pour appeler reactor.stop(). Toute aide ou conseil est apprécié. MerciEst-il possible de définir un délai d'attente sur une socket dans Twisted?

Répondre

5

Depuis Twisted est piloté par les événements, vous n'avez pas besoin d'un délai d'attente en soi. Il vous suffit de définir une variable d'état (comme datagramRecieved) lorsque vous recevez un datagramme et enregistrer un looping call qui vérifie la variable d'état, arrête le réacteur si variable appropriée efface alors l'état:

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

Je pense que reactor.callLater fonctionnerait mieux que LoopingCall. Quelque chose comme ceci:

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

avec le réacteur nous devons utiliser callLater. Démarrer le compte à rebours du délai d'attente lors de la connexionMade. Réinitialiser le compte à rebours du délai d'attente lorsque la ligne est reçue.

Voici le

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

Une meilleure façon de le faire est avec twisted.protocols.policies.TimeoutMixin. Il fait essentiellement un callLater mais a abstraité dans un Mixin.

Questions connexes