2008-10-21 63 views
8

我意识到我可能只是愚蠢的和缺少重要的东西,但我无法弄清楚如何使用reactor.listenUDP指定超时扭曲。我的目标是能够指定一个超时,并且在所述时间量之后,如果DatagramProtocol.datagramReceived尚未执行,请让它执行一个回调函数或我可以用来调用reactor.stop()的函数。任何帮助或建议表示赞赏。谢谢是否可以在Twisted上的套接字上设置超时?

回答

5

因为Twisted是事件驱动的,所以你不需要超时本身。你只需要设置一个状态变量(如datagramRecieved)当您收到一个数据包并注册looping call,检查状态变量,停止反应,如果合适再清除状态变量:

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

我觉得reactor.callLater会更好地工作比LoopingCall。像这样:

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

带反应器我们必须使用callLater。 connectionMade时启动超时倒计时。 lineReceived时重置超时倒计时。

这里的

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

一个更好的办法来做到这一点是twisted.protocols.policies.TimeoutMixin。它本质上是做一个callLater,但抽象成Mixin

相关问题