返回包禁止返回server_twisted系列教程十二–为server 增加一个service

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

Chinese by Yang Xiaowei and Cheng Luo

One More Server

在第九部分和第十部分我们介绍了关于诗歌的变形引擎的想法,最后我们实现了cummingsifier,我们还让它抛出随机的异常来模拟错误.但是假如这个变形的引擎在另外一台服务器上,提供一种网络的”poetry transformation service”, 那么现在又多出来一种出错的方式:变形引擎挂掉了.

所以在第十二部分我们将要实现一个poetry transformation server,并在下一部分,我们让我们的client 使用一个外部的transformation service,并从中学到Deferred 的一些东西.

Designing the Protocol

到现在为止client 和server 端的交互都是单向的,server 端向client端发送一首诗,而client 什么也向server 发送.但是一个transformation service 是双向的– client 端向server发送一首诗然后服务端发送给client 一首变形后的诗.所以我们需要一个新的protocol来处理这种交互.

在我们实现这个的时候,我们让server 支持多种的变形方式,并让client 可以选择使用哪一种.所以client 需要发送给server两个数据:变形的方式和这首诗的内容.我们的server 会返回变化后的诗.所以呢,我们已经完成了一个简单的Remote Procedure Call.

twisted 包含了几个实现这个问题的几种protocol,包括XML-RPC, Perspective Broker, 和 AMP.

但是呢,用这些已经实现了的protocol 会让我们走的太远了,所以最好我们还是自己实现一个.让我们的client 发送一个如下的字符串:

.

也就是一个变形引擎的名字和这首诗歌的内容中间用一个点连接.我们还会把这个字符串编码成netstring 的形式.server 端会返回已经变形过的诗,也是netstring 的方式.因为netstring 使用了带长度的编码,client 可以检测到是否server端发送了一个完整版本的诗.如果你回想一下的话,我们原来的protocol 很难检测到中途停止发送的情况.

有关protocol 的设计先介绍这些,对于我们来说已经够用了.

The Code

让我们来看一下我们的ransformation server,在 twisted-server-1/transformedpoetry.py,首先,我们定义了一个TransformService 类:

class TransformService(object):

def cummingsify(self, poem):

return poem.lower()

这个transform service 目前只支持一种变形–cummingsify.通过一个同名方法.我们还可以增加其他的算法.我们需要注意的是:transformation service 是完全独立于我们之前所说的protocol 的.把protocol 的逻辑和 service 的逻辑分开在twisted 编程中是一个经常用的模式.这样做的话可以通过不同的protocol 来提供相同的transformation service而不用修改太多的代码.

下面让我们看一下protocol factory:

class TransformFactory(ServerFactory):

protocol = TransformProtocol

def __init__(self, service):

self.service = service

def transform(self, xform_name, poem):

thunk = getattr(self, 'xform_%s' % (xform_name,), None)

if thunk is None: # no such transform

return None

try:

return thunk(poem)

except:

return None # transform failed

def xform_cummingsify(self, poem):

return self.service.cummingsify(poem)

这个factory 提供了一个变形的方法,一个protocol 可以用它来得到一个poetry transformation.如果没有这个方法相对应的transformation或这个transformation失败了,这个方法会返回None.就像TransformService 一样,这个protocol factory 和protocol 也是相互独立的,但是factory 中的方法protocol 都是可以调用的.

你需要注意的是我们是怎样保护带有xform_前缀地 方法.这是一种在twisted 源码中经常用的模式.这是一种防止客户端的代码直接调用service 对象方法的方法,因为客户端可能传递过来任何的 transform name.

下面我们来看一下protocol 的实现:

class TransformProtocol(NetstringReceiver):

def stringReceived(self, request):

if '.' not in request: # bad request

self.transport.loseConnection()

return

xform_name, poem = request.split('.', 1)

self.xformRequestReceived(xform_name, poem)

def xformRequestReceived(self, xform_name, poem):

new_poem = self.factory.transform(xform_name, poem)

if new_poem is not None:

self.sendString(new_poem)

self.transport.loseConnection()

在protocol 的实现中我们利用了Twsited 已经实现的NetstringReceiver protocol.这个基类会负责netstring 的编码和解码,我们所要去做的就是实现stringReceived 方法.换句话说,stringReceived会被传递进从client 那边接收过来的诗的内容.这个基类也会负责缓冲传进来的数据直到我们有足够的数据去解码出来一首完整的诗.

假如一切都正常的话我们会通过NetstringReceiver 提供的sendString方法发送变过形的诗到客户端.这就是全部要做的工作.main 函数由于没有什么变化,我们在这里就不讲了.

注意我们是怎样通过定义xformRequestReceived 方法利用twisted 模式将传进来的字节流变化成更高级的抽象,最后xformRequestReceived 被传递进两个参数–一个是变形的名字另一个是诗的内容.

A Simple Client

在第十三部分我们会实现一个利用ransformation service 的twisted client.但现在我们仅仅用一段脚本来测试我们的server,代码在twisted-server-1/transform-test.它用netcat程序向server 发送一首诗歌的内容并打印出返回的结果.让我们先开启我们的server:

python twisted-server-1/transformedpoetry.py --port 11000

然后运行我们的测试脚本:

./twisted-server-1/transform-test 11000

你看看到下面的额输出:

15:here is my poem,

Discussion

在这一部分我们介绍了一些新的想法:

双向的通信

在twisted 已经提供的protocol 实现上进行编程

使用一个service 对象来分开功能逻辑和protocol 逻辑

双向通信的结构是非常简单的,读数据和写数据中我们都使用了同样的技术,与之前的server 和client 不同的是我们同时使用了它们两个.当然,一个更复杂的protocol会需要更复杂的代码来处理字节流,这也是我们为什么使用了一个已经存在的protocol 实现.

一但你熟悉了一些基本的protocol 的实现,建议你去看看twisted 自带的一些复杂的协议.你可以从twisted.protocols.basic 模块读起.写一些简单的protocol 是你熟悉twisted 编程的很好的方式.在一些真正twisted 程序中,更有可能去使用一个已经被实现的protocol.

使用一个service对象来把功能逻辑和protocol逻辑分开在twisted 编程中是一个很重要的设计模式,尽管我们今天将的这个变形的service 不是特别重要,你可以想象在一个大型的应用中一个service可能会非常复杂.通过让service 和 protocol 分离,我们可以快速的在不同的protocol上提供相同的service.

图片二十七描述了一个transformation server通过两种不同的protocol 的来进行服务:

7b7f638bd2b764675cef88790cef6352.png

图片二十七

尽管我们需要两个protocol factory,它们可能也就protocol 不同.这个两个protocol factory共用一个service 对象,剩下的就是protocol 需要分开实现.这样我们就实现了数据复用.

Looking Ahead

有关我们的transformation server 暂时就讲这么多,在第十三部分,我们会继续改进我们的client,让它可以直接利用我们的service.

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值