Twisted的WEB开发

1   简介

在WEB开发中,偶尔需要对HTTP协议更多底层细节进行控制,这时的django/web.py等等显然无法满足要求,所以只好求助于Twisted了。使用Twisted进行WEB开发,其实更合适的叫法应该是基于HTTP服务器的开发,因为Twisted相对底层,所以可以控制的东西也比较底层。

在Twisted的技术体系中,这个WEB开发实际上要涉及到HTTPChannel、HTTPFactory、Request三个层次的开发,以下详诉。

HTTP协议参考 RFC2616 。

2   Twisted技术体系

Twisted技术体系包含2个层次:协议和工厂。协议负责连接成功以后对交互的处理,而工厂则是负责连接过程。在HTTP协议中,连接之后还有个生成HTTP请求报文的过程,所以构造出了一个Request对象来处理具体的一个HTTP请求的报文。

在HTTP中的请求报文处理对象是 twisted.web.http.Request 类;HTTP的协议类是 twisted.web.http.HTTPChannel ;HTTP工厂是 twisted.web.http.HTTPFactory 。

3   一个简单的例子

节选自《Twisted网络编程必备》:

from twisted.web import http

class MyRequestHandler(http.Request):
    pages={
        ‘/‘:‘<h1>Home</h1>Home Page‘,
        ‘/test‘:‘<h1>Test</h1>Test Page‘,
        }
    def process(self):
        if self.pages.has_key(self.path):
            self.write(self.pages[self.path])
        else:
            self.setResponseCode(http.NOT_FOUND)
            self.write("<h1>Not Found</h1>Sorry, no such page.")
        self.finish()

class MyHttp(http.HTTPChannel):
    requestFactory=MyRequestHandler

class MyHttpFactory(http.HTTPFactory):
    protocol=MyHttp

if __name__=="__main__":
    from twisted.internet import reactor
    reactor.listenTCP(8000,MyHttpFactory())
    reactor.run()

与其他很多框架不同,TwistedWEB只有一个核心的请求处理类Request,各个针对不同的URL的请求也要通过这里来分发。而这个类只要重载process() 方法就可以了,期间的很多数据都可以通过self来引用。

请求的处理流程也就是判断对不同URL的不同处理,然后向客户端写入响应信息,并在最后调用关闭请求。步骤如下:

  1. 过滤URL, self.path
  2. self.write(data) 向客户端写入数据
  3. self.finish() 关闭响应

4   Twisted WEB Request参考

来自分析 twisted.web.http.http.py 源代码。

4.1   请求

包含请求的数据,这里都是指Request类的成员。

channel :包含上级的HTTP协议对象。

transport :通信对象。

method :HTTP方法,如GET和POST。

uri :全部请求的URI。

path :具体的请求路径,不含参数。

args :请求参数,包括URL参数和POST参数。格式如 {‘key‘:[‘val1‘,‘val2‘],} 。

received_headers :请求报文的头字段。

received_cookies :请求报文的cookie。

content :请求报文的实体主体,文件对象。

clientproto :发出请求的客户端的HTTP版本。

client :?

host :?

getHeader(key) :获取请求的头字段。

getCookie(key) :获取请求的cookie。

getAllHeaders() :所有请求的头字段字典,就是返回received_headers。

getRequestHostname() :请求的host字段,不含端口号。

getHost() :原始请求的通信地址,返回host。

getClientIP() :获取客户端IP。

getUser() :获取basic验证中的用户名。

getPassword() :获取basic验证中的密码。

getClient() :?

4.2   响应

包含响应的数据,这里都是Request类的成员。

headers :字典,包含响应报文的头字段。

cookies :字典,包含响应报文的cookie。

finish() :结束响应报文。

write(data) :向客户端发送数据,经过了HTTP包装了。

addCookie(k,v,expires=None,domain=None,path=None,max_age=None,comment=None,secure=None):为响应报文添加一个cookie。

setResponseCode(code,message=None) :设置响应代码,code参考常量定义。

setHeader(k,v) :设置头字段。

redirect(url) :HTTP重定向。

setLastModified(when) :设置缓存超时,when的值为长整型的那个时间。

setETag(etag) :设置缓存标志,用于在内容更改时让用户有所发觉。

setHost(host,port,ssl=0) :设置请求地址。用于代理服务器的重定向。

4.3   常量

没有响应主体的code:

NO_BODY_CODES=(204,304)

responses=RESPONSES :字典,保存了各个响应码的对应提示信息。

响应报文中的响应码:

OK=200 :请求处理成功,最常见的响应代码,但是正因为常见,所以默认就是这个了,也无须设置到setResponseCode。

NOT_MODIFIED=304 :请求的资源没有没有修改过,用于浏览器缓存。

BAD_REQUEST=400 :请求报文有语法错误。

UNAUTHORIZED=401 :尚未认证,要求用户输入认证信息。

FORBIDDEN=403 :禁止访问。

NOT_FOUND=404 :请求的资源不存在。

INTERNAL_SERVER_ERROR=500 :服务器内部错误。

NOT_IMPLEMENTED=501 :该功能尚未实现。

BAD_GATEWAY=502 :请求路径错误。

4.4   HTTPChannel

构造函数无参数,处理HTTP报文。

requestFactory=Request :指定了请求报文处理工厂。

4.5   HTTPFactory

__ini__(logPath=None,timeout=60*60*12) :构造函数可以设置日志和超时。

buildProtocol(addr) :内部的构造协议对象的方法,不要调用。

protocol=HTTPChannel :设置协议对象。

5   比较完善的开发模式

建立一个Request类的子类作为请求工厂,或者说请求发布器,其中有识别不同的URL并的能力,通过字典找到该URL对应的函数,调用这个函数并传递self参数。每个具体的请求处理函数也只有1个request参数,返回数据都是直接写入request.write()中。

一般来说请求工厂的process()中需要设置响应类型,如网页的:

self.setHeader("Content-Type","text/html; charset=GB2312")

同时也要在没有对应的URL时告知客户端找不到:

self.setResponseCode(http.NOT_FOUND)
self.write("<h1>Not Found</h1>Sorry, no such page.")
self.finish()

至于self.finish()放在各个请求处理函数中还是放在process(),就是个人爱好问题了。比较推荐放在process()中。

提取请求参数的重点在request.args字典,每个键都是映射到一个列表,为了适应HTTP提交中一个键对应多个值的情况,当然,你也可以只取第一个值。

6   以resource方式提供WEB资源

  1. 每个资源都是 twisted.web.resource.Resource 的子类
  2. 可以自己定义构造函数
  3. 要重载 render(self,request) 方法来响应请求
  4. render 方法中的request对象实际就是Request的实例

一个例子:

from twisted.web import resource,static,server

class HomePage(resource.Resource):

    def render(self,request):
        request.write("Home Page")
        return

    def getChild(self,path,request):
        return AnotherPage() #另外一个Resource的子类

if __name__=="__main__":
    from twisted.internet import reactor
    root=resource.Resource()
    root.putChild(‘‘,HomePage())
    root.putChild(‘color‘,ColorRoot())
    root.putChild(‘style.css‘,static.File(‘style.css‘))
    site=server.Site(root)
    reactor.listenTCP(8000,site)
    reactor.run()

可以通过各个Resource的构造参数传入path参数,用以后来寻找下级Resource的参数。

Note

关于Resource还有很多细节,但是对本文意义不大,所以略。

7   总结

总的来说,用Twisted来开发更适合于开发个框架,而不是直接做WEB应用,有如一直都很少有人直接用 mod_python 来开发WEB应用一样。

时间: 2024-10-22 10:02:03

Twisted的WEB开发的相关文章

Twisted web开发教程

最近在网上看到一篇twisted web开发文章,将它实践了一下,twisted 提供基本的url路由 和 控制器,模板与模型需要外部扩展 1.目录浏览 2.get请求 3.url路由 4.接受带参数的get请求 5.获取和过期session 获取session 手动设置session过期 再获取一次看是否过期 5-1.session实现一个页面计数器 5.2 移除session 6.get与post请求,表单编写

python Web开发的参考书

在网上找了一些 感觉这几个还可以 Web接口开发与自动化测试--基于Python语言 Flask Web开发:基于Python的Web应用开发实战 Python高效开发实战:Django.Tornado.Flask.Twisted Python项目开发实战 HTML5移动平台的Java Web实用项目开发 http://chenx1242.blog.51cto.com/10430133/1914949 http://www.ziqiangxuetang.com/django/django-tem

高性能WEB开发:重排与重绘

DOM编程可能最耗时的地方,重排和重绘. 1.什么是重排和重绘 浏览器下载完页面中的所有组件--HTML标记.JavaScript.CSS.图片之后会解析生成两个内部数据结构--DOM树和渲染树. DOM树表示页面结构,渲染树表示DOM节点如何显示.DOM树中的每一个需要显示的节点在渲染树种至少存在一个对应的节点(隐藏的DOM元素disply值为none 在渲染树中没有对应的节点).渲染树中的节点被称为"帧"或"盒",符合CSS模型的定义,理解页面元素为一个具有填充

[Java Web]2\Web开发中的一些架构

1.企业开发架构: 企业平台开发大量采用B/S开发模式,不管采用何种动态Web实现手段,其操作形式都是一样的,其核心操作的大部分都是围绕着数据库进行的.但是如果使用编程语言进行数据库开发,要涉及很多诸如事务.安全等操作问题,所以现在开发往往要通过中间件进行过渡,即,程序运行在中间件上,并通过中间件进行操作系统的操作,而具体一些相关的处理,如事务.安全等完全由中间件来负责,这样程序员只要完成具体的功能开发即可. 2.Java EE架构: Java EE 是在 Java SE 的基础上构建的,.NE

七日Python之路--第十二天(Django Web 开发指南)

<Django Web 开发指南>.貌似使用Django1.0版本,基本内容差不多,细读无妨.地址:http://www.jb51.net/books/76079.html (一)第一部分 入门 (1)内置数字工厂函数 int(12.34)会创建一个新的值为12的整数对象,而float(12)则会返回12.0. (2)其他序列操作符 连接(+),复制(*),以及检查是否是成员(in, not in) '**'.join('**')   或  '***%s***%d' % (str, int)

Java Web开发基础(3)-JSTL

在DRP项目中接触到了JSTL标签库,对我这样的比較懒的人来说,第一感觉就是"惊艳". JSTL标签库的使用.能够消除大量复杂.繁复的工作.工作量降低的不是一点半点.是降低了一大半.不论什么工具的引入,都会使我们的工作变的简单.可是问题是我们工作能够变的简单,可是我们不能让自己的大脑变的简单.所以,我们不是简单的会用就能够.我们还须要了解这个工具是怎样工作的.怎样为我们提供便利的.ok.以下进入正题,我们从问题開始-- JSP脚本带来的问题 不知道看到这几个子,各位有什么想法?反正我认

给大家分享web开发新手修改hosts文件实现本地域名访问的正确方法

1.如何正确修改hosts文件: 一般打开hosts文件里面都会有个示例,按照其格式修改即可 比如以下内容: # For example: # # 102.54.94.97 rhino.acme.com # source server # 38.25.63.10 x.acme.com # x client host 即代表打开rhino.acme.com这个网址将解析到102.54.94.97,ip地址与网址间至少有一空格,当然建议通过按Table键来编辑,即美观又不容易编写失误;这也就是通过解

java web开发阅读笔记:第一章

学习该书前所用推荐书籍<名师讲坛-java开发实战经典> 一web开发前奏 1.1网页发展 首先搞懂. 1.HTTP:超级文本传输协议,是一种通讯协议. 通过这个网络协议WW浏览器与WWW服务器之间的通讯进行规定,并且通过这个协议我们可以浏览网页,通过网页从客户端写入信息,从服务端得到信息.而通常的HTTP消息包括"客户端->服务端"与"服务端->客户端"的消息传送,图解HTTP协议的功能: 是在客户端通过浏览器根据HTTP协议中向服务器端发

移动Web开发调研

背景 在移动互联网浪潮下,移动设备普及,对配置需要考虑移动端设备可访问性.Web作为最贴近用户的配置手段,面向从PC端传统页面,向移动端页面的转型. 概念 PC Web: 面向传统PC电脑的浏览器开发的Web人机交互界面. 移动Web:面向移动设备的浏览器开发的Web人机交互界面.移动设备包括:手机.Pad等移动设备. 移动APP:面向移动设备开发的APP软件,直接运行于移动设备的系统上.不同于移动Web,其不需要借助中间软件运行. Web APP: 以浏览器为入口,实现 App 的 Web 化