http://blog.sina.com.cn/s/blog_704b6af70100pzhf.html twisted框架学习
twisted为异步网络编程框架
twisted是一个具有强大功能且具有很强健壮性的库,其defer  异步  callback  server application pb等抽象很好的解决了显示中的问题。
一:初步认识
#coding:utf-8
__author__ = 'zhoukunpeng'
from  twisted.internet import reactor
def hello():
    print "hello from the reactor loop!"
reactor.callWhenRunning(hello)
print  "start the reactor"
reactor.run()
reactor.run()进入事件循环。
twisted默认的reactor是用select实现的,上面的这个等效于:
from twisted.internet import  selectreactor
selectreactor.install()
from twisted.internet import  reactor
def hello():
    print "hello from the reactor loop!"
reactor.callWhenRunning(hello)
print "start the reactor"
reactor.run()
修改twisted的默认线程池的大小:
from twisted.internet import reactor
reactor.suggestThreadPoolSize(20)
在twisted中还具有其他的reactor的实现,比较有名的一个就是poll实现的pollreactor。如果你要使用它,可以按照上面的方式进行。
twisted为单线程的。回调不仅仅是一个可选项,而是游戏规则的一部分,因此,我们应该确保回调函数不要浪费时间,要尽快返回。在回调函数中应该尽量避免阻塞I/O的函数。否则,会失去所有reactor所带来的优势。!!
当callback运行的时候reactor是停止的,callback应该尽可能的快!
reactor.stop()用于停止事件循环,reactor stop以后再也无法run!
twisted中如果出现了异常,服务是不会退出的!这就是网络服务器所应有的体格!
在twisted中一个良好的习惯就是,不是传递一个函数,而是传递一个实现了某些接口的对象。这样,可以一次传递多个callback.
twisted提供给我们的多任务的处理方式是合作,twisted会告诉什么时候去读,什么时候去写,但是我们就要在尽可能处理多的数据情况下,又要防止拥塞,此外我们必须避免其他的堵塞的操作。
Twisted网络通信模型中最基本也要由三个部分组成:transports,   protocols,  factory, reactor
连接:代表了一个可以接受和发送数据的连接。 (仅提供了发送数据的方法,接受数据的方法未提供!为什么? 异步啊!)连接建立以后,这个对象也自动被reactor建立
协议:用来完成于一个已经连接成功的主机的交互功能,主要有数据的接受、发送、连接的断开事件也可以在这里处理
工厂:负责于一个协议启动和关闭功能,而且还负责在连接成功时生成一个协议对象。每个连接需要自己的协议,工厂的作用就是当一个连接进来的时候就已经为其准备好了协议。专业生产协议! 一个factory产生的协议均共享这个factory
反应器:用来执行时间循环,分发时间处理等。一个应用程序一般只启动一个reactor
一个典型的Twisted应用程序应该如下:
①. 建立一个协议类,可以从protocol.BaseProtocol类或其子类继承
②. 建立一个工厂 ,可以从protocol.Factory或其子类继承。工厂至少应该制定protocol属性,指向协议类。通常把一些数据库读写的函数建立在工厂内。
③. 启动事件循环,根据连接方向的不同可以选择reactor的connectXXX()或listenXXX()的方法。然后执行reactor.run()启动事件循环。
协议模型:
所有协议的基类是protocol.BaseProtocol其原型如下:
class BaseProtocol:
    connected=0
    transport=None
    def makeConnection(self,transport):不可重载
    def connectionMade(self):#连接成功事件,可以重载
其可以看做为一个虚基类,实现功能比较简陋,实际应用中,一般不直接继承BaseProtocol而是继承Protoclo类!
class Protocol(BaseProtocol):
    def dataReceived(self,data):接收到数据事件,可重载
        pass
    def connectionLost(self,reason=connectionDone):连接断开事件,可重载,依靠reason区分断开类型
        pass
从Protocol类继承就可以完成协议的基本处理了,包括连接的建立和断开事件,还有数据接受事件。
如果想要更加完整的协议功能,twisted.protocols包中寻找!
如果需要自己实现一种协议,比较推荐的是twisted.protocols.basic.LineReceiver类:
LineReceiver默认按照文本行模型进行通信,接受数据也是以行为单位,也可以设置为以原始数据模式进行通信。
比较典型的应用就是HTTPChannel协议类,在头部请求/应答中使用行模式,在实体主体传输时,又是用的原始数据类型。
LineReceiver还是比较实用的。其类结构如下:
class LineReceiver(protocol.Protoclo,_PauseableMixin):
    def clearLineBuffer(self):清空缓冲区
    def setLineMode(self,extra=""):设置工作状态为行模式
    def setRawMode(self):设置工作状态为原始数据模式
    def rewDataReceived(self,data): 原始数据接受事件,可重载
    def lineReceived(self,line): 行模式接受事件,可重载
    def sendLine(self,line): 以行模式发送数据
    发送原始数据可以通过self.transport实现,self.transport是所有的协议对象都拥有的成员,其方法大致如下:
self.transport.write(data)        发送原始数据
self.transport.loseConnection()   关闭连接
self.transport.getPeer()          获取对方信息
self.transport.getHost()          获取本机消息。
工厂模型:
相对于协议,工厂可以发挥的控件就很小了,所有工厂的基类是twisted.internet.proctocol.Factory
这个类定义了三个方法。大致如下:
class Factory:
    protocol=None #指向一个协议类。
    def startFactory(self):  开启工厂,可以重载 
    def stopFactory(self):   关闭工厂,可以重载
    def buildProtocol(self,addr):   构造协议对象,并给协议对象添加一个factory属性指向工厂,可以重载,但注意要再方法内继承原方法内容。
工厂还分为客户端工厂和服务器工厂。
服务器工厂:
class SeverFactory(Factory):
客户端工厂:
class ClientFactory(Factory):
    def startedConnecting(self,connecter): 连接建立成功时事件,可重载
    def clientConnectionFailed(self,connector,reason):客户端连接失败,可重载
    def clientConnectionLost(self,connector,reason):连接断开,可重载
此三个方法都传递了一个connector对象,这个对象有如下方法可以:
connector.stopConnection()关闭对话
connector.connect()    一般在连接失败时,用于重新连接。
本例子中,主要用到了两个类,这两个类用于作为客户端进行工作。
ClientFactory:主要用于管理连接事件,创建Protocol对象,处理成功的连接。
Protocol:主要用于收发数据和决定是否关闭连接。
Protocol对象有一个属性叫做transport,代表当前活动的连接对象。
感悟:
twisted也可以理解为三层的架构:
reactor
  |
factory
  | 
protocol
reactor一般用connectXXX     listenXXX等方法
factory 一定要设置protocol,一般用来控制连接的关闭和重连等。具有reactor操作权利
protocol 是协议的实现部分。     具有factory    transport   reactor操作权利。

posted on 2016-08-08 15:36  wolover  阅读(294)  评论(0编辑  收藏  举报