Twisted

Twisted定义

    Twisted是一个基于事件驱动的网络引擎框架

     网络框架,别人预先定义好的一个框架(一个项目),如.net某个web框架有25个class,从BeginRequest依次执行类里的process方法,程序员自己定义一个类,添加到框架里,应用程序从上到下运行,就会执行自定义代码。框架只知道这个类的列表,不关心你写了什么内容,从上到下执行,类似于一个执行链,C#里叫委托链。也就是把代码类放到这个列表中,委托这个框架替你执行。

    事件驱动(not event),把自定义代码注册到框架中,框架代替你执行。或者框架提供几个接口,让你插入数据(python里没有 )。

    委托不能为空,事件可以为空。

演示一个最简单的框架

前期准备:

     新建一个名为event_drive的python package,里面新建一个event_drive.py文件,这个就是框架主文件,把package目录复制到sys.path中,如:c:python27libsite-package

event_drive.py:

1
2
3
4
5
6
7
8
9
10
11
12
13
event_list = []    #[myclass,]
 
def run():
    for event in event_list:
        obj = event()
        obj.execute()
 
class BaseHandler(object):
    """
    用户必须继承该类,从而规范所有类的方法(类似于接口的功能)
    """
    def execute(self):
        raise Exception('you must overwrite execute')
自定义代码:
1
2
3
4
5
6
7
8
9
from event_drive import event_drive
 
class MyClass(event_drive.BaseHandler):
 
    def execute(self):  #重写execute方法
        print "执行了自定义execute方法"
 
event_drive.event_list.append(MyClass)  #注册到委托链即“注册一个事件”
event_drive.run()
执行过程:    
  1. 导入event_drive文件夹中的event_drive文件

  2. 自定义一个类MyClass,这个类继承了event_drive文件中BaseHandler类

  3. 类里实现execute方法,内容无所谓甚至可以为空,方法名称execute不能改变

  4. 注册事件到框架的委托链,即把类名list.append(MyClass)传进去(下面的Twisted框架是创建对象后改一个字段为类名也是同样的目的)

  5. 执行run方法,框架自己就把MyClass中的方法执行了

执行结果:
1
2
执行了自定义execute方法
Process finished with exit code 0

Twisted框架:以socket为例

安装Twisted:(linux参考如下,windows直接用安装包)

1
2
3
cd Twisted-15.5.0
python setup.py build
python setup.py install

    ps:twisted调用了zope和win32api模块,先安装这两个,要不会报错。

Twisted_server.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from twisted.internet import reactor, protocol
from twisted.web.client import getPage
from twisted.internet import reactor
import time
 
class Echo(protocol.Protocol):    #继承protocol.py中的Protocol类
 
    def dataReceived(self, data):    
        self.transport.write(data)    #将收到的内容直接发送回去
 
factory = protocol.ServerFactory()    #实例化
factory.protocol = Echo    #将自定义类传给对象
 
reactor.listenTCP(8000,factory)    #将端口和实例化对象作为参数传给reactor
reactor.run()
Twisted_client.py
1
2
3
4
5
6
7
8
9
10
11
12
import socket
ip_port=('127.0.0.1',8000)
sk=socket.socket()
sk.connect(ip_port)
sk.settimeout(5)
 
while True:
    inp=raw_input("please input:")
    sk.sendall(inp)
    print sk.recv(1024)
 
sk.close()

执行原理

    跟SocketServer原理类似,内部封装,内部有一个while循环,while循环一旦触发,找到这个类,执行这个类的构造方法,创建对象,通过对象,执行预定义的方法,

源码分析


程序执行流程:

  • 运行服务端程序
  • 创建Protocol的派生类Echo

        解释:自定义Echo类,名字随便起,它继承了Protocol类,Protocol类又继承了BaseProtocol类,有了最左边的图

  • 创建ServerFactory对象,并将Echo类封装到其protocol字段

        解释:ServerSocket是将MyClass以参数的形式封装,这个是以字段的形式

  • 执行reactor的 listenTCP 方法,内部使用 tcp.Port 创建socket server对象,并将该对象添加到了 reactor的set类型的字段 _read 中

        解释:

    1. print type(reactor)
    2. ==>
    3. <class 'twisted.internet.selectreactor.SelectReactor'>

    去selectreactor.SelectReactor中找listenTCP,看上面的类继承关系图,继承了好多类。listenTCP和run方法都在基类里。

    1. def listenTCP(self, port, factory, backlog=50, interface=''):
    2. p = tcp.Port(port, factory, backlog, interface, self)
    3. p.startListening()
    4. return p
    其中把factory对象传入,就相当于:
        1、把Echo类封装到factory字段
        2、再把factory对象封装到listenTCP
        3、tcp.port里创建了socket连接
  • 执行reactor的 run 方法,内部执行 while 循环,并通过 select 来监视 _read 中文件描述符是否有变化,循环中...

    解释:SelectReactor中包含两个集合_reads=set()和_writes=set(),不允许重复的集合,有连接后把文件句柄添加到这个集合中。开始执行reactor.run(),它调用基类里的mainLoop方法,又调取的selectreactor.doInteration,找不到?因为它是个重命名doInteration=doSelect,这个方法里面调取的就是select方法,通过调用select,循环这个_reads。一旦有句柄进来,通过反射去_reads里找“doRead”执行方法。

  • 客户端请求到达

         解释:可以通过debug方式了解调用顺序

  • 执行reactor的 _doReadOrWrite 方法,其内部通过反射调用 tcp.Port 类的 doRead 方法,内部 accept 客户端连接并创建Server对象实例(用于封装客户端socket信息)和 创建 Echo 对象实例(用于处理请求) ,然后调用 Echo 对象实例的 makeConnection 方法,创建连接。
  • 执行 tcp.Server 类的 doRead 方法,读取数据,
  • 执行 tcp.Server 类的 _dataReceived 方法,如果读取数据内容为空(关闭链接),否则,触发Echo 的 dataReceived 方法
  • 执行 Echo 的 dataReceived 方法

    Twisted主要用于网络操作,它支持许多常见的传输及应用层协议,包括TCP、UDP、SSL/TLS、HTTP、IMAP、SSH、IRC以及FTP。其中包含了诸多功能,例如:网络协议、线程、数据库管理、网络操作、电子邮件等。

优点

  • 使用基于事件驱动的编程模型,而不是多线程模型。

  • 跨平台:为主流操作系统平台暴露出的事件通知系统提供统一的接口。

  • “内置电池”的能力:提供流行的应用层协议实现,因此Twisted马上就可为开发人员所用。

  • 符合RFC规范,已经通过健壮的测试套件证明了其一致性。

  • 能很容易的配合多个网络协议一起使用。

  • 可扩展。

一个非常全面介绍Twisted网站

    http://twisted.readthedocs.org/en/twisted-15.5.0/
















原文地址:https://www.cnblogs.com/daliangtou/p/5091226.html