twisted python_twisted系列教程十一—一个twisted 的服务端

原文:http://krondo.com/blog/?p=1209

Chinese by Yang Xiaowei and Cheng Luo

A Twisted Poetry Server

既然我们已经学了这么多twisted client 的编写,现在让我们来用twisted来重新实现一下我们的poetry server 吧.我们要多谢谢twisted 抽象的普遍性,貌似我们已经学了twisted 的我们需要知道的大部分东西了.看下我们的twisted poetry server twisted-server-1/fastpoetry.py,它被叫做fastpoetry 应为这个server可以尽可能快的发送一首诗.它的代码要比cilent 中的代码要少.

让我们一次分析一小段的代码,首先,PoetryProtocol:

class PoetryProtocol(Protocol):

def connectionMade(self):

self.transport.write(self.factory.poem)

self.transport.loseConnection()

就像client 一样,server 用了一个单独的protocol 实例来管理每一个不同的连接.这里的protocol 是我们server端的poetry protocol.因为我的protocol 是严格的单向的(one-way不知道怎么翻译),server protocol 实例仅仅需要关心发送数据.我们的protocol 需要在连接建立之后立即开始传送数据,所以我们实现了connectionMade 方法,它是一个callback,在一个protocol 实例连接上一个transport之后触发.

我们的connectionMade方法让transport 去做两件事:发送整首诗的内容(self.transport.write)和关闭连接(self.transport.loseConnection).当然,这两个操作都是异步的.所以write方法的调用意味着”最后我会把所有的数据都送出去”,close方法的调用意味着”一但我让你送的数据都送完了再关闭这个连接”.

正如你看到的,protocol 从factory那里接受整首诗歌的内容,就像下面的代码所描述的:

class PoetryFactory(ServerFactory):

protocol = PoetryProtocol

def __init__(self, poem):

self.poem = poem

我们的factory 真正干的工作除了创建PoetryProtocol 的实例以外,也保存了PoetryProtocol 需要的poem 的内容.

注意我们这里实现的是ServerFactory而不是ClientFactory.因为我们的server 是被动的监听连接,我们不需要ClientFactory提供的额外的方法.我们是怎么确定要用 ServerFactory的呢?因为我们要用reactor 的listenTCP 方法,手册中讲到那个方法的factory 参数需要是一个ServerFactory 的实例.

下面是main 函数:

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,

interface=options.iface)

print 'Serving %s on %s.' % (poetry_file, port.getHost())

reactor.run()

它已经做了三件事情:

读取我们将要服务的诗的内容

创建一个PoetryFactory

用listenTCP去告诉twsited 在一个端口上监听连接,并用我们的factory为每一个连接 创建protocol 的实例

做完这些之后,剩下的要做的事情就是告诉reactor 开始循环.你可以用以前咱们写的client 测试一下.

Discussion

回想一下在五部分的图片八和图片九.这些图片描述了一个新的protocol 实例是怎样在twisted 创建一个新的连接之后被创建和初始化的.在server 端twisted 接受一个新来的连接也是采用了同样的原理.那就是为什么 connectTCP 和 listenTCP都需要一个factory 的参数.

在图片九中我们没有描述的是connectionMade callback 会在Protocal 初始化的时候被调用,不管什么情况下都会发生的,但是我们在client 用不到它.我们在client 中用到的一些protocol 方法在server 的protocol 中也不会用到.如果我们想折腾的话,我们可以写一个统一的protocol,又可以用在客户端又可用在服务端,在twisted 中的一些protocol 也确实是这么做的.例如,NetstringReceiver protocol 既可以用来从Transport中读也可以向Transport 中写.

我们暂时就不写一个low-level 的poetry server了,但是我们要想明白这个twisted server到底做了什么.首先,调用listenTCP 让twisted 创建一个监听的socket并把它加入到事件循环里面.这个socket 上的事件并不是告诉你有数据可读了,而是告诉你有一个client 在等待要连上来.

twisted 会自动的接收传过来的连接请求,并创建一个client socket 连接server 和 client.这个client socket也被加入事件循环,然后twisted 创建一个新的transport 和 一个PoetryProtocol 的实例来为这个client socket 服务. 所以Protocol 实例是一直和client socket 连着的,而不是负责监听的socket.

图片二十六描述了这个过程:

fbc3c7d453ff4d169a1add4a81ab0ec3

图片二十六

在这张图片中有三个client 连接着poetry server.每一个Transport 代表了一个client socket,listening socket 总共创建了四个文件描述符并让select loop 来监测.当一个client 断开跟它关联的Transport,PoetryProtocol 会被间接引用被被垃圾回收器回收.同时PoetryFactory会继续存在只要我们还在监听新的连接到来.

client sockets 和他们关联的python 对象不会活太久如果我们要处理的诗很短的话.但是如果有成千上百的并发的client 的话,我们的poetry server 会垮掉.twisted 本身对同时能处理的连接数量并没有内置的限制.当然,随着你不断增加server 的负载,你会发现你的server最后会撑不住,或者达到了操作系统内部的限制.对于高负载的系统来说,认真的抗压测试是非常重要的.

twisted 对我们能监听的端口的数量也没有限制.实际上,一个twisted 的进程可以监听n多的端口并在不同的端口提供不同的服务.

我们的server 还少很多东西.首先,它没有记录任何的可以帮助我们进行dedug 或者分析网络流浪的日志.在一个是,这个server 不是以守护进程来运行的,这就让它很容易挂掉,比如不小心按了Ctrl-C,或者登出了.我们在将来都会修复这些问题.在第十二部分,我们将会写令一个可以变换诗的server.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值