2008-10-21 23 views
8

Me doy cuenta de que probablemente soy tonto y me falta algo grande e importante, pero no puedo encontrar la manera de especificar un tiempo de espera en twisted usando reactor.listenUDP. Mi objetivo es poder especificar un tiempo de espera, y después de dicha cantidad de tiempo, si DatagramProtocol.datagramReceived no se ha ejecutado, haga que ejecute una devolución de llamada o algo que pueda usar para llamar a reactor.stop(). Cualquier ayuda o consejo es apreciado. Gracias¿Es posible establecer un tiempo de espera en un socket en Twisted?

Respuesta

5

Dado que Twisted es un evento controlado, no necesita un tiempo de espera per se. Usted sólo tendrá que establecer una variable de estado (como datagramRecieved) cuando se recibe un datagrama y registrar una looping call que comprueba la variable de estado, se detiene el reactor en su caso a continuación, se borra la variable de estado:

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

Creo reactor.callLater funcionaría mejor que LoopingCall. Algo como esto:

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

con reactor debemos usar callLater. Cuenta atrás del tiempo de espera de inicio cuando connectionMade. Restablecer la cuenta atrás del tiempo de espera cuando se recibe la línea.

Aquí está la

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

Una mejor manera de hacerlo es con twisted.protocols.policies.TimeoutMixin. Básicamente está haciendo un callLater, pero se abstrajo en un Mixin.

Cuestiones relacionadas