文档章节

(转) Twisted :第十一部分 改进诗歌下载服务器

水果糖
 水果糖
发布于 2016/01/27 13:22
字数 1673
阅读 13
收藏 0

诗歌下载服务器

到目前为止,我们已经学习了大量关于诗歌下载客户端的Twisted的知识,接下来,我们使用Twisted重新实现我们的服务器端。利益于Twisted的抽象机制,接下来你会发现我们前面已经几乎全部学习到这部分知识了。其实现源码在twisted-server-1/fastpoetry.py。之所以称其为fastpoetry是因为其并没有任何延迟的传输诗歌。注意到,其代码量比客户端少多了。

让我们一部分一部分地来看服务端的实现,首先是poetryProtocol

class PoetryProtocol(Protocol):
    def connectionMade(self):
        self.transport.write(self.factory.poem)
        self.transport.loseConnection()


如同客户端的实现,服务器端使用Protocol来管理连接(在这里,连接是由客户端发起的)。这里的Protocol实现了我们的诗歌下载逻辑的服务器端。由于我们协议逻辑处理的是单向的,服务器端的Protocol只负责发送数据。如果你访问服务器端,协议请求服务器在连接建立后立即发送诗歌,因此我实现了connectionMade方法,其会在Protocol中创建一个连接时被激活执行。

这个方法告诉Transport做两件事:将整首诗歌发送出去然后关闭连接。当然,这两个动作都是同步操作。因此调用write函数也可以说成“一定要将整首诗歌发送到客户端”,调用loseConnection意味着“一旦将要求下载的诗歌发送完毕就关掉这个连接”。

也许你看到了,Protocol是从Factory中获得诗歌内容的:

class PoetryFactory(ServerFactory):
    protocol = PoetryProtocol
    def __init__(self, poem):
        self.poem = poem


这么简单!除了创建PoetryProtocol工厂的仅有的工作是存储要发送的诗歌。

注意到我们继承了ServerFactory而不是ClientFactory。这是因为服务器是要被动地监听连接状态而不是像客户端一样去主动的创建。我们何以如此肯定呢?因为我们使用了listenTCP方法,其描述文档声明factory参数必须是ServerFactory类型的。

我们在main函数中调用了listenTCP函数:

def main():
    options, poetry_file = parse_args()
    poem = open(poetry_file).read()
    factory = PoetryFactory(poem)
    from twisted.internet import reactor
    port = reactor.listenTCP(options.port or 0, factory,nterface=options.iface)
    print 'Serving %s on %s.' % (poetry_file, port.getHost())
    reactor.run()


其做了三件事:

1.读取我们要发呈现的诗歌

2.创建PoetryFactory并传入这首诗歌

3.使用listenTCP来让Twisted监听指定的端口,并使用我们提供的factory来为每个连接创建一个protocol

剩下的工作就是reactor来运转事件循环了。你可以使用前面任何一个客户端来测试这个服务器。


讨论

回忆下第五部分中的图8与图9.这两张图说明了一个协议在Twisted创建一个连接后如何创建一个协议并初始化它的。其实对于Twisted在其监听的端口处接听到一个连接之后的整个处理机制也是如此。这也是为什么connectTCPlistenTCP都需要一个factory参数的原因。

我们在图9中没有展示是的,connectionMake其实也是Protocol初始化的一部分。无论在哪儿都一样(Dave是想说,connectionMade都会在Protocol初始化时执行),但我们在客户端处没有用到这个方法。并且我们在客户端的协议实现中的方法并没有在服务器处用到。因此,如果我们有这个需要,可以创建一个共享式的单一PoetryProtocol供客户端与服务器端使用。这各方式在Twisted经常见到。例如,NetstringReceiver protocol即能读从一个连接中读也能向一个连接中写netstrings

我们略去了写从低层来实现服务器端的内容,但我们仍要来思考一下下面发生的事情。首先,调用listenTCP来告诉Twisted创建一个 listening socket 并将其添加到事件循环中。在 listening socket 有事件发生并不意味有数据要读,而是说明有客户端在等待连接自己。

Twisted会自动接受连接请求,并创建一个新客户端式连接来连接客户端与服务器(中间桥梁)。这个新的连接也要加入事件循环中,并且Twisted为其创建了一个Transport与一个专门为这个连接服务的PoetryProtocol。因此,Protocol实例总是连接到客户端式的socket,而不是监听式socket

我们可以在图26中形象地看到这一结果:

第十一部分:改进诗歌下载服务器

26:服务器端的网络连接

在图中,有三个客户端连接到服务器。每个Transport代表一个client socket,加上listening socket总共是四个被select循环监听的文件描述符(file descriptor).当一个客户端断开与其相关的transport的连接时,对应的PoetryProtocol也会被解引用并当作垃圾被回收。而PoetryFactory只要我们还在监听新的连接就会一直不停地工作(即PoetryFactory不会将PoetryProtocol会随着一个连接的断开而被销毁)。

如果我们提供的诗歌很短的话,那么这些client socket与其相关的各种对象的生命期也就很短。但也有可能会是一台相当繁忙的服务器以至于同时有千百个客户端同时请求较长的诗歌。那没关系,因为Twisted并没有连接建立的限制。当然,当下载量持续的增加,在某个结点处,你会发现已经到达了OS的上限。对于那些高下载量的服务器,仔细的检测与测试是每天都必须的工作。

并且Twisted在监听端口的数量上亦无限制。实际上,一个单一的Twisted线程可以监听数个端口并为其提供不同的服务(通过使用不同的factory作为listenTCP的参数即可)。并且经过精心的设计,使用一个Twisted线程来提供多个服务还是使用多个Twisted线程来实现可以推迟到部署阶段来做决定。

我们这个版本的服务器有些功能是没有的。首先,它无法产生任何日志来帮助我们调试和分析网络出现的问题。另外,服务器也不是做为一个守护进程来运行,很容易通过ctrl+c来中止其执行。我们将会在第十二部分来分析这部分内容。

本文转载自:http://blog.sina.com.cn/s/blog_704b6af70100py9n.html

共有 人打赏支持
水果糖
粉丝 15
博文 157
码字总数 52251
作品 0
深圳
程序员
(转) Twisted : 第十二部分 改进诗歌下载服务器

新的服务器实现 这里我们要新写一个Twisted版的服务器。然后,再来讨论一些Deferred的新功能。 在第九、十部分,我们提出了诗歌转换引擎这个概念。由于其实现太过简单,因此我们用随机选择来...

水果糖
2016/01/27
12
0
(转) Twisted :第六部分 抽象地利用Twisted

打造可以复用的诗歌下载客户端 我们在实现客户端上已经花了大量的工作。最新版本的(2.0)客户端使用了Transports,Protocols和Protocol Factories,即整个Twisted的网络框架。但仍有大的改进...

水果糖
2016/01/27
5
0
(转) Twisted :第五部分 Twisted支持的诗歌客户端

抽象地构建客户端 在第四部分中,我们构建了第一个使用Twisted的客户端。它确实能很好地工作,但仍有提高的空间。 首先是,这个客户端竟然有创建网络端口并接收端口处的数据这样枯燥的代码。...

水果糖
2016/01/27
9
0
(转) Twisted : 第十四部分 Deferred用于同步环境

介绍 这部分我们要介绍Deferred的另外一个功能。便于讨论,我们设定如下情景:假设由于众多的内部网请求一个外部诗歌下载服务器,但由于这个外部下载服务器性能太差或请求负荷太重。因此,我...

水果糖
2016/01/27
12
0
(转) Twisted : 第二部分 异步编程初探与reactor模式

第二部分:低效的诗歌服务器来启发对Twisted机制的理解 这个系列是从这里开始的,欢迎你再次来到这里来。现在我们可能要写一些代码。在开始之前,我们都做出一些必要的假设。 关于对你的假设 ...

水果糖
2016/01/27
24
0

没有更多内容

加载失败,请刷新页面

加载更多

sourcetree 离线免注册登录安装教程

Sourcetree是一个优秀的git可视化管理工具,深受开发者喜爱Sourcetree官网,但是在安装时需要谷歌账户登录,需要翻qiang才可以,此一点一直被人们所诟病。今天本教程就为大家提供离线免登陆安...

QQZZFT
15分钟前
1
0
使用 PostgreSQL 解决一个实际的统计分析问题

使用 PostgreSQL 解决一个实际的统计分析问题作者:老农民(刘启华)Email: 46715422@qq.com 之前有个朋友扔给我一个奇葩需求,他们公司之前做了一批问卷调查,全部都是统一格式的excel...

新疆老农民
18分钟前
1
0
TypeScript基础入门之高级类型的映射类型

转发 TypeScript基础入门之高级类型的映射类型 高级类型 映射类型 一个常见的任务是将一个已知的类型每个属性都变为可选的: interface PersonPartial {    name?: string;    age?...

durban
33分钟前
1
0
Dubbo源码分析(6):Dubbo内核实现之基于SPI思想Dubbo内核实现

SPI接口定义 定义了@SPI注解 package com.alibaba.dubbo.common.extension; import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.an......

郑加威
34分钟前
1
0
RxJS的另外四种实现方式(后记)—— 同时实现管道和链式编程

目录 RxJS的另外四种实现方式(序) RxJS的另外四种实现方式(一)——代码最小的库 RxJS的另外四种实现方式(二)——代码最小的库(续) RxJS的另外四种实现方式(三)——性能最高的库 Rx...

一个灰
37分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部