twisted 的延遲對象deferred

deferred 「異步」功能的實現,與多線程徹底不一樣,具備如下特色:

1. deferred 產生的 event,是函數調用返回的對象;

2. deferred 表明一個鏈接任務,負責報告任務執行的延遲狀況和最終結果;

3. 對deferred 的操做,經過預約的「事件響應器」(event handler)進行。

defer的使用方式:

1). 在factory中建立deferred對象,但在調用factory對象以外返回自身的deferred對象,
而後再添加callback和errback, 具體示例以下:
#! /usr/bin/env python
#coding=utf-8
from twisted.internet import reactor, defer, protocol
class CallbackAndDisconnectProtocol(protocol.Protocol):
     def connectionMade(self):
        self.factory.deferred.callback("Connected!")
        # self.transport.loseConnection()

class ConnectionTestFactory(protocol.ClientFactory):
    protocol = CallbackAndDisconnectProtocol

    def __init__(self):
        self.deferred = defer.Deferred()   

    def clientConnectionFailed(self, connector, reason):
        self.deferred.errback(reason)

def testConnect( port):
     testFactory = ConnectionTestFactory()
     reactor.listenTCP(port, testFactory)
     return testFactory.deferred
def handleSuccess(result, port):
     #deferred "event-responsor": handle finished connection
     print 'result-----',result
     print "Connected to port %i" % port
     # reactor.stop()

def handleFailure(failure, port):
     print "Error connecting to port %i: %s" % (port, failure.getErrorMessage())
     # reactor.stop()

if __name__ == '__main__':
    port = 50001
    conndefer = testConnect(port)
    conndefer.addCallback(handleSuccess, port)
    conndefer.addErrback(handleFailure, port)
    reactor.run()


2). 不顯示建立deferred對象, 在函數返回時,咱們調用defer.succeed(results)函數。
其中result則能夠爲調用咱們延時操做函數返回的結果。示例以下:
#! /usr/bin/env python
#coding=utf-8
from twisted.internet import protocol, reactor, defer
from twisted.protocols import basic

class FingerProtocol(basic.LineReceiver):
    def lineReceived(self, user):
         self.factory.getUser(user
             ).addErrback(lambda _: "Internal error in server"
             ).addCallback(lambda m:
                           (self.transport.write(m+"/r/n")))

class FingerFactory(protocol.ServerFactory):
     protocol = FingerProtocol

     def __init__(self, **kwargs):
        self.users = kwargs
        print self.users
     def getUser(self, user):
         return defer.succeed(self.users.get(user, "No such user"))

if __name__ == '__main__':
     reactor.listenTCP(1077, FingerFactory(hd='Hello my python world'))
     reactor.run()
相關文章
相關標籤/搜索