2015-01-20 145 views
1

我的问题是这样的: 我有一个扭曲的服务器,它每隔2秒通过TCP发送一个值,并带有callLater。而且我有一个扭曲的客户,它接受了价值,并且应该用延期来处理收受价值。Twisted推迟定期调用

我的服务器看起来是这样的:

from twisted.internet.protocol import ServerFactory 
from twisted.protocols.basic import NetstringReceiver 
from random import randint 

class ServerProtocol(NetstringReceiver): 
    def __init__(self, factory): 
     self.factory = factory 
     self.sendObject = None 

    def connectionMade(self):   
     self.sendValue() 

    def connectionLost(self, reason): 
     sendObject, self.sendObject = self.sendObject, None 
     sendObject.cancel() 

    def sendValue(self): 
     data = randint(2,20) 
     self.sendString(str(data)) 
     print('send: {0}'.format(data)) 

     from twisted.internet import reactor 
     self.sendObject = reactor.callLater(2, self.sendValue) 

class MyServerFactory(ServerFactory): 

    def __init__(self): 
     self.protsa = [] 

    def buildProtocol(self, addr): 
     return ServerProtocol(self) 

    def setCallback(self, callback): 
     self.callback = callback  

def serverMain(): 

    factory = MyServerFactory() 
# factory.setCallback(generateVal) 

    from twisted.internet import reactor 

    port = reactor.listenTCP(2345, factory, interface='127.0.0.1')  
    print 'Serving on %s.' % (port.getHost()) 

    reactor.run() 


if __name__ == '__main__': 
    serverMain() 

我的客户是这样的:

from twisted.internet.protocol import ClientFactory 
from twisted.protocols.basic import NetstringReceiver 
from twisted.internet import defer 


class ClientProtocol(NetstringReceiver): 

    def stringReceived(self, string): 
     print("recieved") 
     self.factory.printValue(string) 

    def connectionMade(self): 
     print("Made Connection") 

    def connetionLost(self): 
     print("Connection Lost") 

class MyClientFactory(ClientFactory): 

    protocol = ClientProtocol 

    def __init__(self, deferred): 
     self.deferred = deferred 

    def clientConnectionFailed(self, connector, reason): 
     if self.deferred is not None: 
      d, self.deferred = self.deferred, None 
      d.errback(reason) 

    def printValue(self, value): 
     if self.deferred is not None: 
      d, self.deferred = self.deferred, None 
      d.callback(value) 


def OutputValue(host, port): 
    d = defer.Deferred() 
    from twisted.internet import reactor 
    factory = MyClientFactory(d) 
    reactor.connectTCP(host, port, factory) 
    return d 

def clientMain(): 

    def writeError(err): 
     print("Deferred Error!\n") 
     print("Error: {0}".format(err.__str__)) 

    def writeValue(value): 
     print("Value revieved: {0}".format(value)) 

    from twisted.internet import reactor 

    d = OutputValue('127.0.0.1', 2345) 
    d.addCallbacks(writeValue, writeError) 

    reactor.run() 

if __name__ == '__main__': 
    clientMain() 

输出:

Made Connection 
recieved 
Value revieved: 11 
recieved 
recieved 
recieved 

首次一切工作正常。连接后,服务器发送客户端收到的值。客户一直希望延期。第二个值不是由延期处理的。我也预计,因为推迟只发射一次。 现在我想有一个可能性来处理延迟的每个接收值,所以我也可以做错误处理。

我看看这个:

Twisted: deferred that fires repeatedly

Re-using deferred objects in Twisted

,但我不能让我的问题的解决方案的保持。这不可能如此不寻常。 或者我每次都必须断开连接吗?

回答

0

Deferred是一个代表您正在制作的特定请求结果的对象。但是由于一个请求只能有一个关联的响应,就像一个函数只能返回一次一样,一个Deferred只能被触发一次。

您已拥有一项功能 - printValue - 在接收到值并应打印时运行。为什么不直接在该函数中打印值,而不是去寻找你的调用者设置的延迟?

+0

我完全知道我生成的代码只能通过延迟给出一个返回值。但我只是学习扭曲,并正在这样做:http://krondo.com/?page_id=1327教程。我在那里得到了一个印象,只有通过使用延迟才能实现扭曲的正确错误处理。所以我想在这种情况下也使用延期。 – MightyAsator 2015-01-21 13:40:42

+0

你可以用一个简单的'try:'/'来处理错误,除了:像在Python中一样。对这种情况使用延期并不会给你带来太多的收益。 – Glyph 2015-01-22 23:19:36