欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Twisted服务器开发技巧(1)

程序员文章站 2023-11-10 15:34:52
twisted是一个非常具有想像力的框架。我已经被它的代码所折服,我想在我下面再使用python开发网络应用时,可能只会选用twisted了。但是,一个真正达到性能优化服务器,还是...

twisted是一个非常具有想像力的框架。我已经被它的代码所折服,我想在我下面再使用python开发网络应用时,可能只会选用twisted了。但是,一个真正达到性能优化服务器,还是需要我们在程序中真正良好的去应用twisted的各种工具的。 最常见的情况就是我们将一个非阻塞的应用中,加入了长时间的处理过程,从而达到了阻塞的效果,从而让大家都因为一位同志的长时工作而等待。


先来看看下面的这段代码:


   1 from twisted.internet import protocol, reactor
   2 from twisted.protocols import basic
   3 class fingerprotocol(basic.linereceiver):
   4     def linereceived(self, user):
   5         self.transport.write(self.factory.getuser(user)+"\r\n")
   6         self.transport.loseconnection()
   7 class fingerfactory(protocol.serverfactory):
   8     protocol = fingerprotocol
   9     def __init__(self, **kwargs): self.users = kwargs
  10     def getuser(self, user):
  11         return self.users.get(user, "no such user")
  12 reactor.listentcp(1079, fingerfactory(hd='hello my python world'))
  13 reactor.run()
它可能是我们所写的第一个twisted服务器。可能所有人都会认为这样的操作已经不会有什么问题了。但是显然,在这里我们的getuser更多的情况下可能会是从中或是ldap服务器上获取相关的信息。哪么最好的处理就是将get操作以非即时方式返回,以避免发生处理的阻塞。哪么就需要使用deferreds了:


   1 from twisted.internet import protocol, reactor, defer
   2 from twisted.protocols import basic
   3 class fingerprotocol(basic.linereceiver):
   4     def linereceived(self, user):
   5         self.factory.getuser(user
   6         ).adderrback(lambda _: "internal error in server"
   7         ).addcallback(lambda m:
   8                       (self.transport.write(m+"\r\n"),
   9                        self.transport.loseconnection()))
  10 class fingerfactory(protocol.serverfactory):
  11     protocol = fingerprotocol
  12     def __init__(self, **kwargs): self.users = kwargs
  13     def getuser(self, user):
  14         return defer.succeed(self.users.get(user, "no such user"))
  15 reactor.listentcp(1079, fingerfactory(hd='hello my python world'))
  16 reactor.run()
这里getuser返回的是defer处理过的一个事务,而addcallback方法注册了defer中处理完成后的返回事件。这样,事务的处理就可以在另一个事件可调度的情况下进行了。从而避免了因一个用户的处理阻塞的情况下,让所有的用户都停止了响应。