天天看点

《Python核心编程(第3版)》——2.6 *Twisted框架介绍

本节书摘来自异步社区《python核心编程(第3版)》一书中的第2章,第2.6节,作者[美] wesley chun(卫斯理 春),孙波翔 李斌 李晗 译,更多章节内容可以访问云栖社区“异步社区”公众号查看。

twisted是一个完整的事件驱动的网络框架,利用它既能使用也能开发完整的异步网络应用程序和协议。在编写本书时,因为它还不是python标准库的一部分,所以必须单独下载并安装它(可以使用本章末尾的链接)。它提供了大量的支持来建立完整的系统,包括网络协议、线程、安全性和身份验证、聊天/ im、dbm及rdbms数据库集成、web/因特网、电子邮件、命令行参数、gui集成工具包等。

使用twisted来实现简单的例子,有点小题大做,但是你必须开始使用它,并且该应用程序就相当于网络应用程序的“hello world”。

与socketserver类似,twisted的大部分功能都存在于它的类中。特别是对于该示例,我们将使用twisted因特网组件中的reactor和protocol子包中的类。

你会发现示例2-10中的代码类似于socketserver例子中的代码。然而,相比于处理程序类,我们创建了一个协议类,并以与安装回调相同的方式重写了一些方法。另外,这个例子是异步的。现在就让我们看一下服务器代码。

示例2-10 twisted reactor时间戳tcp服务器(tstservtw.py)

《Python核心编程(第3版)》——2.6 *Twisted框架介绍

逐行解释

第1~6行

设置行代码包括常用模块导入,尤其是twisted.internet的protocol和reactor子包以及常数端口号的设置。

第8~14行

我们获得protocol类并为时间戳服务器调用tsservprotocol。然后重写了connectionmade()和datareceived()方法,当一个客户端连接到服务器时就会执行connectionmade()方法,而当服务器接收到客户端通过网络发送的一些数据时就会调用datareceived()方法。reactor会作为该方法的一个参数在数据中传输,这样就能在无须自己提取它的情况下访问它。

此外,传输实例对象解决了如何与客户端通信的问题。你可以看到我们如何在connectionmade()中使用它来获取主机信息,这些是关于与我们进行连接的客户端的信息,以及如何在datareceived()中将数据返回给客户端。

第16~20行

在服务器代码的最后部分中,创建了一个协议工厂。它之所以被称为工厂,是因为每次得到一个接入连接时,都能“制造”协议的一个实例。然后在reactor中安装一个tcp监听器,以此检查服务请求。当它接收到一个请求时,就会创建一个tsservprotocol实例来处理那个客户端的事务。

与socketserver tcp客户端不同,示例2-11看起来与其他客户端都不同,这个是明显的twisted。

示例2-11 twisted reactor时间戳tcp客户端(tstclnttw.py)

《Python核心编程(第3版)》——2.6 *Twisted框架介绍

再一次,除了导入twisted组件之外,并没有什么新内容。它与其他的客户端非常类似。

第8~22行

类似于服务器,我们通过重写connectionmade()和datareceived()方法来扩展protocol,并且这两者都会以与服务器相同的原因来执行。另外,还添加了自己的方法senddata(),当需要发送数据时就会调用它。

因为这次我们是客户端,所以我们是开启与服务器对话的一端。一旦建立了连接,就进行第一步,即发送一条消息。服务器回复之后,我们就将接收到的消息显示在屏幕上,并向服务器发送另一个消息。

以上行为会在一个循环中继续,直到当提示输入时我们不输入任何内容来关闭连接。此时,并非调用传输对象的write()方法发送另一个消息到服务器,而是执行loseconnection()来关闭套接字。当发生这种情况时,将调用工厂的clientconnectionlost()方法以及停止reactor,结束脚本执行。此外,如果因为某些其他的原因而导致系统调用了clientconnectionfailed(),那么也会停止reactor。

在脚本的最后部分创建了一个客户端工厂,创建了一个到服务器的连接并运行reactor。注意,这里实例化了客户端工厂,而不是将其传递给reactor,正如我们在服务器上所做的那样。这是因为我们不是服务器,需要等待客户端与我们通信,并且它的工厂为每一次连接都创建一个新的协议对象。因为我们是一个客户端,所以创建单个连接到服务器的协议对象,而服务器的工厂则创建一个来与我们通信。

与其他客户端类似,twisted客户端也展示了输出。

服务器恢复到单个连接。twisted会保持连接,在每条消息发送后不会关闭传输。

“connection from”的输出并不包含其他信息,因为我们只从服务器传输对象的getpeer()方法请求了主机/地址。

需要记住的是,大多数基于twisted的应用程序都比本节给出的例子更加复杂。因为这是一个功能丰富的库,但是它确实有一定的复杂度,所以你需要做好准备。