Twisted 框架 初印象

 

上面是twisted官網推薦的書籍,從封面能夠看到,是一堆大蟒(python)糾纏在一塊兒,這裏能夠說明twisted是一個基於pyhton語言,支持各類網絡協議(包括UDP,TCP,TLS和其餘應用層協議,好比HTTP,SMTP,NNTM,IRC,XMPP/Jabber。)使用(糾纏)的較低層的通訊框架,twisted框架已經實現了這些協議,咱們只須要使用就好了。另外twisted框架是基於事件驅動
 
下面是搬運官網的例子:
 
TCP服務器
from twisted.internet import protocol, reactor, endpoints class Echo(protocol.Protocol): 
    def dataReceived(self, data): 
        self.transport.write(data) 
class EchoFactory(protocol.Factory): 
    def buildProtocol(self, addr): 
       return Echo()

endpoints.serverFromString(reactor, "tcp:1234").listen(EchoFactory()) reactor.run()        

  

web服務器
from twisted.web import server, resource 
from twisted.internet import reactor, endpoints class Counter(resource.Resource): 
    isLeaf = True 
    numberRequests = 0 
    def render_GET(self, request): 
        self.numberRequests += 1 
        request.setHeader(b"content-type", b"text/plain") 
        content = u"I am request #{}\n".format(self.numberRequests)                                                                              
return content.encode("ascii") endpoints.serverFromString(reactor, "tcp:8080").listen(server.Site(Counter()))

reactor.run()

 

聊天室
from twisted.internet import reactor, protocol, endpoints
from twisted.protocols import basic

class PubProtocol(basic.LineReceiver):
    def __init__(self, factory):
        self.factory = factory

    def connectionMade(self):
        self.factory.clients.add(self)

    def connectionLost(self, reason):
        self.factory.clients.remove(self)

    def lineReceived(self, line):
        for c in self.factory.clients:
            source = u"<{}> ".format(self.transport.getHost()).encode("ascii")
            c.sendLine(source + line)

class PubFactory(protocol.Factory):
    def __init__(self):
        self.clients = set()

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

endpoints.serverFromString(reactor, "tcp:1025").listen(PubFactory())
reactor.run()

你可使用打開兩個命令行終端,使用 telnet localhost 1025, 而後在每一個終端輸入。python

 
郵件客戶端
twisted 包含了一個複雜的 imap4 客戶端庫
from __future__ import print_function

import sys

from twisted.internet import protocol, defer, endpoints, task
from twisted.mail import imap4
from twisted.python import failure

@defer.inlineCallbacks
def main(reactor, username="alice", password="secret",
         strport="tls:example.com:993"):
    endpoint = endpoints.clientFromString(reactor, strport)
    factory = protocol.Factory.forProtocol(imap4.IMAP4Client)
    try:
        client = yield endpoint.connect(factory)
        yield client.login(username, password)
        yield client.select('INBOX')
        info = yield client.fetchEnvelope(imap4.MessageSet(1))
        print('First message subject:', info[1]['ENVELOPE'][1])
    except:
        print("IMAP4 client interaction failed")
        failure.Failure().printTraceback()

task.react(main, sys.argv[1:])

 

總結react

twisted 是一個封裝了各個網絡協議,基於事件循環驅動的框架。web

1. 要使用twisted框架,需實現一個twisted Protocol類的客戶端或服務器類,重寫其dataReceived,api

定義接受到對端數據時的處理方法。服務器

2. 對於服務器類(客戶端類),還要實現一個twisted Factory(ClientFactory)類,用來管理Protocol類,當有新的客戶端鏈接時,框架調用網絡

Factory.buildProtocol()返回Protocol類去處理相應鏈接。框架

3. 使用twisted  相應的listen/connect方法,監聽/鏈接對端服務。socket

4. 最後,調用twisted的事件循環處理類reactor.run(),啓動事件循環。tcp

 
 
下面是twisted的關鍵術語:
BaseProtocol
twisted框架全部協議類的基類,其實現了兩個關鍵方法, makeConnection和connectionMade。
makeConnection繼承給子類,通常咱們不使用此方法;
connctionsMade繼承給子類,子類重寫該方法。在客戶端鏈接創建時調用,能夠作一些鑑權之類的操做,也能夠限制客戶端的鏈接總數。
 
class BaseProtocol:
"""
This is the abstract superclass of all protocols.
 
Some methods have helpful default implementations here so that they can
easily be shared, but otherwise the direct subclasses of this class are more
interesting, L{Protocol} and L{ProcessProtocol}.
"""
connected = 0
transport = None
 
def makeConnection(self, transport):
"""Make a connection to a transport and a server.
 
This sets the 'transport' attribute of this Protocol, and calls the
connectionMade() callback.
"""
self.connected = 1
self.transport = transport
self.connectionMade()
 
def connectionMade(self):
"""Called when a connection is made.
 
This may be considered the initializer of the protocol, because
it is called when the connection is completed. For clients,
this is called once the connection to the server has been
established; for servers, this is called after an accept() call
stops blocking and a socket has been received. If you need to
send any greeting or initial message, do it here.

  

Protocol
from twisted.internet.protocol import Protocol
twisted框架爲基於TCP協議等上層協議定義的基類(基於UDP協議的是DatagramProtocol,from twisted.internet.protocol import Protocol),服務端和客戶端都需繼承此類。
其api十分簡單,重寫dataReceived方法支持客戶端有數據發送時的邏輯;重寫connectionLost方法,能夠根據失敗緣由作一些錯誤處理。
 
class Protocol(BaseProtocol):
"""
This is the base class for streaming connection-oriented protocols.
 
If you are going to write a new connection-oriented protocol for Twisted,
start here. Any protocol implementation, either client or server, should
be a subclass of this class.
 
The API is quite simple. Implement L{dataReceived} to handle both
event-based and synchronous input; output can be sent through the
'transport' attribute, which is to be an instance that implements
L{twisted.internet.interfaces.ITransport}. Override C{connectionLost} to be
notified when the connection ends.
 
Some subclasses exist already to help you write common types of protocols:
see the L{twisted.protocols.basic} module for a few of them.
"""
 
def logPrefix(self):
"""
Return a prefix matching the class name, to identify log messages
related to this protocol instance.
"""
return self.__class__.__name__
 
 
def dataReceived(self, data):
"""Called whenever data is received.
 
Use this method to translate to a higher-level message. Usually, some
callback will be made upon the receipt of each complete protocol
message.
 
@param data: a string of indeterminate length. Please keep in mind
that you will probably need to buffer some data, as partial
(or multiple) protocol messages may be received! I recommend
that unit tests for protocols call through to this method with
differing chunk sizes, down to one byte at a time.
"""
 
def connectionLost(self, reason=connectionDone):
"""Called when the connection is shut down.
 
Clear any circular references here, and any external references
to this Protocol. The connection has been closed.
 
@type reason: L{twisted.python.failure.Failure}

  

Factory
from twisted.internet.protocol import Factory
twisted中的Factory子類起到對Protocol類的管理做用,當有新的客戶端鏈接時,框架會調用Factory.buildProtocol(),此時,用戶需在此時將自定義的Protocol實例傳進去,而且做爲該函數的返回值。
 
ClientFactory
from twisted.internet.protocol import ClientFactory
實現客戶端鏈接程序管理的工廠類,需用reactors.connectXXX(如connectTCP) 指定與使用哪一種網絡協議的服務器通訊。
ClientFactory繼承自Factory類,可是比Factory多了3個能夠重寫的事件響應函數,即startedConnecting()在創建鏈接時被調用;clientConnectionLost()在鏈接斷開時被調用;
clientConnectionFailed()在鏈接創建失敗時被調用。
相關文章
相關標籤/搜索