http twisted
Twisted的WEB开发
作者: | gashero <harry.python@gmail.com> |
---|
目录
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的不同处理,然后向客户端写入响应信息,并在最后调用关闭请求。步骤如下:
- 过滤URL, self.path
- self.write(data) 向客户端写入数据
- 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资源
- 每个资源都是 twisted.web.resource.Resource 的子类
- 可以自己定义构造函数
- 要重载 render(self,request) 方法来响应请求
- 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应用一样。
Posted in Twisted | No Comments »
使用twisted.python.log日志
Monday, September 10th, 2007
使用twisted.python.log日志
目录
版本: | 2.4.0 |
---|
1 简单使用
Twisted提供了一个简单而且可移植的日志系统叫做 twisted.python.log 。它包含3个函数:
msg
记录一条信息,例如:
from twisted.python import log
log.msg("hello, world")
err
把错误写入日志,包括traceback信息。你可以传递一个 failure 或者异常的实例,甚至什么都没有。如果传递其他的东西则会通过 repr() 函数获得字符串来显示。如果什么都不传递则会自动构造一个 Failure 实例,一般用于 except 子句:
try:
x=1/0
except:
log.err() #会自动记录ZeroDivisionError
startLogging
通过一个类似文件对象来开始日志,例如:
log.startLogging(open("/var/log/foo.log",'w'))或者:
log.startLogging(sys.stdout)
缺省条件下,startLogging会同时将输出重定向到sys.stdout和sys.stderr。你可以在startLogging中设置setStdout=False来禁用这个功能。
1.1 日志与twistd
如果你使用twistd来运行你的程序作为后台进程,则他会自动托管startLogging,甚至还会自动轮训日志。查看 twistd and tac 一节或twistd的man手册了解更多。
1.2 日志文件
twisted.python.logfile 模块提供了一些可以同startLogging共同使用的类,例如 DailyLogFile ,提供了以天为单位的日志轮询。
2 编写日志监视器
日志监视器是Twisted日志系统的基础。一个日志监视器的例子是供startLogging使用的 FileLogObserver ,可以把事件写入文件中。一个日志监视器是可调用的,并且只接受一次字典作为参数。随后你可以用它来接收所有的日志事件(当然也会给其他日志监视器):
twisted.python.log.addObserver(yourCallable)
字典至少有2个项目:
message
日志信息,一个列表或字符串,被log.msg或log.err传递过来的。
isError
一个布尔值,如果为True时就是从log.err过来的。如果为True说明字典当中还会有个Failure对象。
其他项目是自动被加入的:
printed
这条信息是从sys.stdout中捕获的,例如这条信息是从print输出的。如果isError同样为True,则是从sys.stderr来的。
你可以通过 log.msg 或 log.err 传递附加项目到事件字典。标准的日志监视器将会忽略他们不用的字典参数。
Note
注意
- 不要在日志监视器中抛出异常,否则会挂掉。
- 不要在日志监视器中阻塞,尤其是在主线程中。这将会导致很多问题。
- 日志监视器需要线程安全。
http twisted的更多相关文章
- Mina、Netty、Twisted一起学(八):HTTP服务器
HTTP协议应该是目前使用最多的应用层协议了,用浏览器打开一个网站就是使用HTTP协议进行数据传输. HTTP协议也是基于TCP协议,所以也有服务器和客户端.HTTP客户端一般是浏览器,当然还有可能是 ...
- Twisted随笔
学习了socket后决定尝试使用框架,目标锁定了Twisted. 什么是Twisted? twisted是一个用python语言写的事件驱动的网络框架,他支持很多种协议,包括UDP,TCP,TLS和其 ...
- Python 安装Twisted 提示python version 2.7 required,which was not found in the registry
由于我安装Python64位的,下载后没注册,安装Twisted时老提示“python version 2.7 required,which was not found in the registry ...
- Python - twisted web 入门学习之一
原文地址:http://zhouzhk.iteye.com/blog/765884 python的twisted框架中带了一个web server: twisted web.现在看看怎么用. 一)准备 ...
- Twisted
Twisted是一个事件驱动的网络框架,其中包含了诸多功能,例如网络协议,线程,数据库管理,网络操作,电子邮件等 事件驱动 一,注册事件 二,触发事件 自定义事件框架 event_fram.py # ...
- Mina、Netty、Twisted一起学(十):线程模型
要想开发一个高性能的TCP服务器,熟悉所使用框架的线程模型非常重要.MINA.Netty.Twisted本身都是高性能的网络框架,如果再搭配上高效率的代码,才能实现一个高大上的服务器.但是如果不了解它 ...
- Mina、Netty、Twisted一起学(九):异步IO和回调函数
用过JavaScript或者jQuery的同学都知道,JavaScript特别是jQuery中存在大量的回调函数,例如Ajax.jQuery的动画等. $.get(url, function() { ...
- Mina、Netty、Twisted一起学(七):发布/订阅(Publish/Subscribe)
消息传递有很多种方式,请求/响应(Request/Reply)是最常用的.在前面的博文的例子中,很多都是采用请求/响应的方式,当服务器接收到消息后,会立即write回写一条消息到客户端.HTTP协议也 ...
- Mina、Netty、Twisted一起学(六):session
开发过Web应用的同学应该都会使用session.由于HTTP协议本身是无状态的,所以一个客户端多次访问这个web应用的多个页面,服务器无法判断多次访问的客户端是否是同一个客户端.有了session就 ...
- Mina、Netty、Twisted一起学(五):整合protobuf
protobuf是谷歌的Protocol Buffers的简称,用于结构化数据和字节码之间互相转换(序列化.反序列化),一般应用于网络传输,可支持多种编程语言. protobuf如何使用这里不再介绍, ...
随机推荐
- 决策树减支问题(优化)dfs减支问题
#include <iostream>#include <cstdio>using namespace std;int mem[200];//开记忆数组int fib(int ...
- Oracle Database XE 11gR2 自带的用户,新建用户,修改用户密码
操作系统:Windows 10 x64 第一节:下载 Oracle Database XE 11gR2 第二节:安装.验证安装 Oracle Database XE 11gR2 第三节:Oracle ...
- frp内网穿透
原理 frp(fast reverse proxy)分为Server端和Client端,Server端安装在带有公网IP的服务器上,Client安装在内网环境但能上网的普通PC中. 流程: Serve ...
- 搭建Leanote私有云服务器
安装流程 安装Golang 安装Leanote 安装Mongodb 配置Leanote 初始化Mongodb数据 运行Leanote 安装Golang # 下载go1.14.4.linux-amd64 ...
- A4988两相四线步进电机驱动模块使用经验
1.A4988模块可以驱动两相四线步进电机,模块引脚及接线图如下: 2.步进电机引线如下: 3.引脚: ENABLE:低电平有效,用于打开和关闭场效应管的输出: RESET:低电平有效,芯片复位: S ...
- CPU 执行程序的秘密,藏在了这 15 张图里
前言 代码写了那么多,你知道 a = 1 + 2 这条代码是怎么被 CPU 执行的吗? 软件用了那么多,你知道软件的 32 位和 64 位之间的区别吗?再来 32 位的操作系统可以运行在 64 位的电 ...
- 【LGR-070】洛谷 3 月月赛-官方题解
本次免费为大家提供[LGR-070]洛谷 3 月月赛的官方题解,点个赞再走呗! 代码就不上了,大家可以到别的博客上去找找!希望这篇博客能对你有所帮助!
- Apple uses Multipath TCP
http://blog.multipath-tcp.org/blog/html/2018/12/15/apple_and_multipath_tcp.html December 15, 2018 Ap ...
- postgreSQL与Kingbase 字符串裁剪区别
--postgreSQL postgres=# select substring('abcdefg',0,4); substring abc (1 行记录) postgres=# select sub ...
- es使用--新建、删除、增删改数据
# 进入bin目录 cd /czz/elsearch/bin # 后台启动(不加-d参数则是前台启动,日志在控制台) # 后台启动日志如果不配置,在es目录的logs下面 ./elasticsearc ...