1、介绍
tornado是一个Python web框架和异步网络库 起初由 FriendFeed 开发. 通过使用非阻塞网络I/O, Tornado 可以支持上万级的连接,处理 长连接, WebSockets, 和其他 需要与每个用户保持长久连接的应用.
Tornado 大体上可以被分为4个主要的部分:
- web框架 (包括创建web应用的
RequestHandler
类,还有很多其他支持的类). - HTTP的客户端和服务端实现 (
HTTPServer
andAsyncHTTPClient
). - 异步网络库 (
IOLoop
andIOStream
), 为HTTP组件提供构建模块,也可以用来实现其他协议. -
- ioloop.py 主要的是将底层的epoll或者说是其他的IO多路复用封装作异步事件来处理。
- iostream.py主要是对于下层的异步事件的进一步封装,为其封装了更上一层的buffer(IO)事件。
- 协程库 (
tornado.gen
) 允许异步代码写的更直接而不用链式回调的方式.
Tornado web 框架和HTTP server 一起为 WSGI 提供了一个全栈式的选择. 在WSGI容器 (WSGIAdapter
) 中使用Tornado web框架或者使用Tornado HTTP server 作为一个其他WSGI框架(WSGIContainer
)的容器,这样的组合方式都是有局限性的. 为了充分利用Tornado的特性,你需要一起使用Tornado的web框架和HTTP server.
2、Web应用结构
通常一个Tornado web应用包括一个或者多个 RequestHandler
子类, 一个可以将收到的请求路由到对应handler的 Application
对象,和 一个启动服务的 main()
函数.
一个简单的tornado应用:
import tornado.ioloop import tornado.web class MainHandler(tornado.web.RequestHandler): def get(self): # self.write("Hello, world") 被用于非模板基础的输 出; 它接受字符串, 字节, 和字典(字典会被编码成JSON). # self.render('s1.html') #渲染模板文件,默认在当前目录下找 # self.render('template/s1.html')#html文件集中放在template文件夹中,让其在该文件夹下找 self.render('s1.html') #如果我们不想每次都写template的话,我们可以配置一下它,让其默认就是在该路径下查找 self.get_argument('xxx',None) # 获取用户提交的数据 #配置 settings={ 'template_path':'template' ,#模板路径的配置 'static_path':'static' #静态文件必须要给它配置一下,不然加载是找不到的 } #路由映射,路由系统 application = tornado.web.Application([ (r"/index", MainHandler), ] ,**settings)#应用到tornado中,使其生效 # Application对象是负责全局配置的, 包括映射请求转发给处理程序的路由表. if __name__ == "__main__": application.listen(8888) tornado.ioloop.IOLoop.instance().start()
Application对象
Application对象是负责全局配置的, 包括映射请求转发给处理程序的路由表.
路由表是 URLSpec
对象(或元组)的列表, 其中每个都包含(至少)一个正则 表达式和一个处理类. 顺序问题; 第一个匹配的规则会被使用. 如果正则表达 式包含捕获组, 这些组会被作为 路径参数 传递给处理函数的HTTP方法. 如果一个字典作为 URLSpec
的第三个参数被传递, 它会作为 初始参数 传递给RequestHandler.initialize
. 最后 URLSpec
可能有一个名字 , 这将允许它被RequestHandler.reverse_url
使用.
例如, 在这个片段中根URL /
映射到了 MainHandler
, 像 /story/
后跟着一个数字这种形式的URL被映射到了 StoryHandler
. 这个数字被传递(作为字符串)给 StoryHandler.get
.
class MainHandler(RequestHandler): def get(self): self.write('<a href="%s">link to story 1</a>' % self.reverse_url("story", "1")) class StoryHandler(RequestHandler): def initialize(self, db): self.db = db def get(self, story_id): self.write("this is story %s" % story_id) app = Application([ url(r"/", MainHandler), url(r"/story/([0-9]+)", StoryHandler, dict(db=db), name="story") ])
Application 构造函数有很多关键字参数可以用于自定义应用程序的行为 和使用某些特性(或者功能); 完整列表请查看 Application.settings
.