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()在链接创建失败时被调用。
相关文章
相关标签/搜索