Python Twisted系列教程11:改进诗歌下载服务器
作者:dave@http://krondo.com/your-poetry-is-served/ 译者:杨晓伟(采用意译)
你可以从这里从头阅读这个系列。
诗歌下载服务器
到目前为止,我们已经学习了大量关于诗歌下载客户端的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在其监听的端口处接听到一个连接之后的整个处理机制也是如此。这也是为什么connectTCP与listenTCP都需要一个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来中止其执行。我们将会在第十二部分来分析这部分内容。
Python Twisted系列教程11:改进诗歌下载服务器的更多相关文章
- Python Twisted系列教程8:使用Deferred的诗歌下载客户端
作者:dave@http://krondo.com/deferred-poetry/ 译者:杨晓伟(采用意译) 可以从这里从头开始阅读这个系列. 客户端4.0 我们已经对deferreds有些理解了 ...
- Python Twisted系列教程6:抽象地利用Twisted
作者:dave@http://krondo.com/and-then-we-took-it-higher/ 译者:杨晓伟(采用意译) 你可以从这里从头开始阅读这个系列. 打造可以复用的诗歌下载客户端 ...
- Python Twisted系列教程14:Deferred用于同步环境
作者:dave@http://krondo.com/when-a-deferred-isnt/ 译者:杨晓伟(采用意译) 你可以从这里从头开始阅读这个系列. 介绍 这部分我们要介绍Deferred的 ...
- Python Twisted系列教程10:增强defer功能的客户端
作者:dave@http://krondo.com/an-introduction-to-asynchronous-programming-and-twisted/ 译者:杨晓伟(采用意译) 可以从这 ...
- Python Twisted系列教程12:改进诗歌下载服务器
作者:dave@http://krondo.com/a-poetry-transformation-server/ 译者:杨晓伟(采用意译) 你可以从这里从头阅读这个系列. 新的服务器实现 这里我们 ...
- Python Twisted系列教程5:由Twisted支持的诗歌客户端
作者:dave@http://krondo.com/twistier-poetry/ 译者:杨晓伟(采用意译) 你可以从这里从头开始阅读这个系列 抽象地构建客户端 在第四部分中,我们构建了第一个使用 ...
- Python Twisted系列教程4:由Twisted支持的诗歌客户端
作者:dave@http://krondo.com/twisted-poetry/ 译者:杨晓伟(采用意译) 你可以在这里从头开始阅读这个系列. 第一个twisted支持的诗歌服务器 尽管Twist ...
- Python Twisted系列教程9:第二个小插曲,Deferred
作者:dave@http://krondo.com/a-second-interlude-deferred/ 译者:杨晓伟(采用意译) 可以从这里从头来阅读这个系列 更多关于回调的知识 稍微停下来再思 ...
- Python Twisted系列教程20: Twisted和Erlang
作者:dave@http://krondo.com/twisted-and-erlang/ 译者: Cheng Luo 你可以从”第一部分 Twist理论基础“开始阅读:也可以从”Twisted 入 ...
随机推荐
- visualvm监控jvm及远程jvm监控方法
VisualVM是Sun的一个OpenJDK项目,其目的在于为Java应用创建一个整套的问题解决工具.它集成了多个JDK命令工具的一个可视化工具,它主要用来监控JVM的运行情况,可以用它来查看和浏览H ...
- zoj 3212 K-Nice(构造)
K-Nice Time Limit: 1 Second Memory Limit: 32768 KB Special Judge This is a super simple pr ...
- python基础之迭代器协议和生成器(二)
一.什么是迭代器: 迭代是Python最强大的功能之一,是访问集合元素的一种方式. 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束. 迭代器是一个可以记住遍历的位置的对象. 迭代器的 ...
- Android 用户界面---定制组件(Custom Components)
基于布局类View和ViewGroup的基本功能,Android为创建自己的UI界面提供了先进和强大的定制化模式.首先,平台包含了各种预置的View和ViewGroup子类---Widget和layo ...
- zoj-3963 Heap Partition(贪心+二分+树状数组)
题目链接: Heap Partition Time Limit: 2 Seconds Memory Limit: 65536 KB Special Judge A sequence ...
- 从微软官网下载VS离线安装包的方法
这里描述是包括所有版本,截图以下载VS2017社区版为例: ①登入VS官网下载页面,选择需要的版本点击下载,下载页点此进入. ②下载完成后,打开下载文件所在文件夹,Windows 8.1及以上版本用户 ...
- HDU - 6333:Harvest of Apples (组合数前缀和&莫队)
There are n n apples on a tree, numbered from 1 1 to n n . Count the number of ways to pick at most ...
- FreeMarker配置详解
首先需要添加freemarker.jar到项目,如果项目中有spring或者spirngmvc,需要整合,首先配置freemarkerConfig,代码结构如下: <!-- 设置 ...
- Dropping tests(二分加01数字)
个人心得:不能说题目太难,而是自己思维太菜,我开始以为这怎么都想不到的,但是学长说不是很简单吗,好吧我信了,我太low. 其实单纯二分只用于搜索,但是这种逆向答案二分确实比较难理解.给大神代码 [一些 ...
- Android中的service
1.service简介:service可以在和多场合的应用中使用,比如播放多媒体的时候用户启动了其他Activity这个时候程序要在后台继续播放,比如检测SD卡上文件的变化,再或者在后台记录你地理信息 ...