原创博文,转载请注明出处

当服务器接收到一个客户端请求后,会创建一个请求对象并传递到资源系统,资源系统会根据请求路径分发到相应的资源对象,资源被要求渲染自身并返回结果到客户端。

解析HTTP Requests:

twisted.web.http.Request描述了一个HTTP request,我们可以从其中发现处理request的方法。

 1 from twisted.internet import reactor
2 from twisted.web import http
3
4 class MyRequestHandler(http.Request):
5 resources={
6 '/':'<h1>Home</h1>Home page',
7 '/about':'<h1>About</h1>All about me',
8 }
9 def process(self):
10 self.setHeader('Content-Type','text/html')
11 if self.resources.has_key(self.path):
12 self.write(self.resources[self.path])
13 else:
14 self.setResponseCode(http.NOT_FOUND)
15 self.write("<h1>Not Found</h1>Sorry, no such source")
16 self.finish()
17
18 class MyHTTP(http.HTTPChannel): #继承高级API http.HTTPChannel
19 requestFactory=MyRequestHandler
20
21 class MyHTTPFactory(http.HTTPFactory):
22 def buildProtocol(self,addr):
23 return MyHTTP()
24
25 reactor.listenTCP(8000,MyHTTPFactory())
26 reactor.run()

执行程序后,在浏览器输入http://localhost:8000/http://localhost:8000/about 看看发生了什么吧

处理 GET request:

from twisted.web.server import Site

from twisted.web.static import File

利用Site,我们不在担心HTTP协议的细节问题,这是http.HTTPFactory的子类,可以管理HTTP会话并且把resources 分发给我们。

from twisted.internet import reactor
from twisted.web.server import Site
from twisted.web.static import File root = File('/var/www/mysite')
root.putChild("doc",File("/usr/share/doc"))
root.putChild("logs",File("/var/log/mysitelogs"))
factory=Site(root)
reactor.listenTCP(8000,factory)
reactor.run()

现在访问 http://localhost:8000/将会得到来自本地文件系统/var/www/mysite的内容回应,访问 localhost:8000/doc将会得到/usr/share/doc的内容回应,

访问localhost:8000/logs将会得到来自/var/log/mysitelogs的内容回应。本人测试在windows环境下尚且无法支持,留着以后再来研究。

提供动态内容:

与提供静态内容不同的是,你需要定义一个继承自Resource的子类去决定一个Site所能提供的内容。

from twisted.internet import reactor
from twisted.web.resource import Resource
from twisted.web.server import Site import time class ClockPage(Resource):
isLeaf=True
def render_GET(self,request):
return "The local time is %s"%(time.ctime(),) resource=ClockPage()
factory=Site(resource)
reactor.listenTCP(8000,factory)
reactor.run()

关于Resource的API文档:点击进入

我们需要定义render_GET render_POST render_HEAD等等“render_METHOD”(其中METHOD是HTTP做出请求的方法)

render_METHOD methods are expected to return a string which will be the rendered page, unless the return value is twisted.web.server.NOT_DONE_YET, in which case it is this class's responsibility to write the results to request.write(data), then call request.finish().

isleaf变量用来描述一个source是否拥有子类,如果设置为False,访问所有的URL将会产生404NO such resource

from twisted.internet import reactor
from twisted.web.resource import Resource,NoResource
from twisted.web.server import Site from calendar import calendar class YearPage(Resource):
def __init__(self,year):
Resource.__init__(self)
self.year=year def render_GET(self,request):
return "<html><body><pre>%s</pre></body></html>"%(calendar(self.year),) class CalendarHome(Resource):
def getChild(self,name,request):
if name=='':
return self
if name.isdigit():
return YearPage(int(name))
else:
return NoResource() def render_GET(self,request):
return "<html><body>Welcome to the calendar server!</body></html>" root=CalendarHome()
factory=Site(root)
reactor.listenTCP(8000,factory)
reactor.run()

本例示范了一个日历服务器,如输入http://localhost:8000/2012就可以显示2012全年的日历,

Redirects重定向:

from twisted.web.util import redirectTo

我们修改上例中CalendarHome

from twisted.web.util import redirectTo
from datetime import datetime def render_GET(self,request):
return redirectTo(datetime.now().year,request)

当我们访问http://localhost:8000/时,datetime.now().year就会作为参数链接在URL的后面即http://localhost:8000/2013

处理POST Requests:

from twisted.internet import reactor
from twisted.web.resource import Resource
from twisted.web.server import Site
import cgi class FormPage(Resource):
isLeaf=True
def render_GET(self,request):
return """
<html>
<body>
<form method="POST">
<input name="form-field" type="text"/>
<input type="submit"/>
</form>
</body>
</html>
""" def render_POST(self,request):
return """
<html>
<body>You submitted: %s</body>
</html>
"""%(cgi.escape(request.args["form-field"][0],)) #cgi.escape(s,[quote,])把在s中的“&”、“<”和“>”转化成HTML安全序列 使用request.args字典存取提交的HTML表单数据 factory=Site(FormPage())
reactor.listenTCP(8000,factory)
reactor.run()

异步处理:

如果发生了请求阻塞,这时候我们就应该使用异步处理方法。

先看一个例子:

from twisted.internet import reactor
from twisted.web.resource import Resource
from twisted.web.server import Site import time class BusyPage(Resource):
isLeaf=True
def render_GET(self,request):
time.sleep(5)
return "Finally done, at %s"%(time.asctime(),) factory=Site(BusyPage())
reactor.listenTCP(8000,factory)
reactor.run()

对于每一次请求我们等待5秒钟,加入我们在浏览器中打开多个标签并输入http://localhost:8000/,我们会发现服务器的回应是连续的,也就是说这几个回应所显示的时间依次相差5秒钟,第一个打开的页面和最后一个打开的页面相差N*5秒,这对于我们将是灾难性的。所以我们有必要进行异步处理。

我们看一下改进的程序:我们使用了deferred,在本例程中你可能会发现requests也是连续的,这是由于你所用的浏览器对于同一resource的请求连续。

# -*- coding: cp936 -*-
from twisted.internet import reactor
from twisted.internet.task import deferLater
from twisted.web.resource import Resource
from twisted.web.server import Site, NOT_DONE_YET import time class BusyPage(Resource):
isLeaf=True def _delayedRender(self,request):
request.write("Fianlly done, at %s"%(time.asctime(),))#渲染网页
request.finish() def render_GET(self,request):
d=deferLater(reactor,5,lambda:request)#返回一个由request引起的deferred
d.addCallback(self._delayedRender)
return NOT_DONE_YET#它告知Resource有些事情是异步的而且尚未完成,直到你调用了request.finish() factory =Site(BusyPage())
reactor.listenTCP(8000,factory)
reactor.run()

twisted学习笔记 No.2 WebServer的更多相关文章

  1. twisted学习笔记No.3 Web Clients

    原创博文,转载请注明出处. 这一章我们学习利用twisted建立web 客户端. twisted.web.client.getPage用来异步下载一个页面,并且返回一个deferred from tw ...

  2. twisted学习笔记 No.1

    原创博文,转载请注明出处 . 1.安装twisted ,然后安装PyOpenSSL(一个Python开源OpenSSL库),这个软件包用于给Twisted提供加密传输支持(SSL).最后,安装PyCr ...

  3. twisted学习笔记4 部署Twisted 应用程序

    原创博文,转载请注明出处. Twisted是一个可扩展,跨平台的网络服务器和客户端引擎. Twisted Application 框架有五个主要基础部分组成:服务,应用程序,TAC文件插件和twist ...

  4. twisted 学习笔记二:创建一个简单TCP客户端

    #coding=utf-8 from twisted.internet import reactor,protocol class QuickClient(protocol.Protocol): de ...

  5. twisted 学习笔记一:事件循环

    from twisted.internet import reactor import time def printTime(): print "Current time is", ...

  6. 【Ext.Net学习笔记】01:在ASP.NET WebForm中使用Ext.Net

    Ext.NET是基于跨浏览器的ExtJS库和.NET Framework的一套支持ASP.NET AJAX的开源Web控件,包含有丰富的Ajax运用,其前身是Coolite. 下载地址:http:// ...

  7. Ext.Net学习笔记01:在ASP.NET WebForm中使用Ext.Net

    Ext.Net是一个对ExtJS进行封装了的.net控件库,可以在ASP.NET WebForm和MVC中使用.从今天开始记录我的学习笔记,这是第一篇,今天学习了如何在WebForm中使用Ext.Ne ...

  8. Visual Studio 2015 Owin+MVC+WebAPI+ODataV4+EntityFrawork+Identity+Oauth2.0+AngularJS 1.x 学习笔记

    2016年,.net 会有很多大更新 ASP.NET 5 在此之前我都是用着古老的.net做开发的 (WebForm + IIS) 为了接下来应对 .net 的新功能,我特地去学习了一下基本的 MVC ...

  9. shell学习笔记

    shell学习笔记 .查看/etc/shells,看看有几个可用的Shell . 曾经用过的命令存在.bash_history中,但是~/.bash_history记录的是前一次登录前记录的所有指令, ...

随机推荐

  1. sharepoint 2013 更改用户配置文件属性值的方法 modify user profile

    在此前写了两篇文章sharepoint 的UserProfile博客 sharepoint 2010 获取用户信息UserProfile方法 sharepoint 2010 怎样用SocialComm ...

  2. C语言星号的秘密

    C语言星号的秘密 星号的秘密 1.乘法运算符   2.定义指针 int *p = 0; 还是 int* p = 0;? 后一种比较容易这样理解:定义了一个变量p,它是指针型的(更详细一点,是指向int ...

  3. 由于问题引起信号ORA-27154无法启动数据库

    测试库运行startup当系统提示(11.2.0.1): 查询ORA-27154的错误: Error: ORA-27154 Text: post/wait create failed -------- ...

  4. android ListView之BaseAdapter的使用方式

    通常在使用自己定义适配器的时候,我们都会掌握一种固定的模式.充分利用convertView+缓存的方式. private ArrayList<ListBean> list ; privat ...

  5. android网络操作使用汇总(http)

    Android是作为智能手机的操作系统,我们开发的应用,大多数也都须要连接网络,通过网络发送数据.获取数据,因此作为一个应用开发人员必须熟悉怎么进行网络訪问与连接. 通常android中进行网络连接通 ...

  6. Zepto

    移动开发流量省起来之Zepto 事情是这样的:最近开发的一个手机网站客户反应访问起来特别慢,刷了半天才能看到页面,然后问我们是不是网站出问题了.于是我赶紧找了各种手机测试一下,没有问题,首先排除程序错 ...

  7. C#中如何获取系统环境变量

    原文:C#中如何获取系统环境变量 C#中获取系统环境变量需要用到Environment Class.其中提供了有关当前环境和平台的信息以及操作它们的方法.该类不能被继承. 以下代码得到%systemd ...

  8. 【phpMyAdmin】更改配置文件连接到其他server

    默认phpMyAdmin安装完毕后对机器的访问mysql,但有时我们需要访问其它server的mysql数据库,所以我们需要配置. 真,phpMyAdmin已经为我们做了配置的选项.可是须要我们进行一 ...

  9. VMware安装CentOS 图文教程

    VMware安装CentOS 图文教程 VMware 下安装CentOS6.2 取消 Easy install模式(此模式不好,很多软件没有安装) http://jingyan.baidu.com/a ...

  10. 如何使用AdvancedInstaller在安装包中运行一个.bat文件

    原文:如何使用AdvancedInstaller在安装包中运行一个.bat文件 1,  首先要保证你的Files and Folders模块下的Application Folder文件夹下包含你要运行 ...