Tornado是FriendReed使用的可扩展的非阻塞式的web服务器及其相关工具的开源版本。
这个框架看起来有些像web.py或者Google的webapp,不过为了能有效利用非阻塞服务器环境,这个框架还包含了一些相关的有用工具和优化。
Tornado和现在的主流Web服务器框架(包含大多数Python的框架)有着明显的区别:它是非阻塞式服务器,而且速度相当快。
得力于其非阻塞的方式和对epoll的运用,Tornado每秒可以处理数以千计的连接,这意味着对于实时Web服务来说,Tornado是一个理想的Web框架。
Tornado的安装:
pip install tornado
源码安装
https://pypi.python.org/packages/source/t/tornado/tornado-4.3.tar.gz
一、快速上手
#!/usr/bin/env python # -*- coding:utf-8 -*- import tornado.ioloop import tornado.web class MainHandler(tornado.web.RequestHandler): def get(self): self.write("Hello, world") application = tornado.web.Application([ (r"/index", MainHandler), ]) if __name__ == "__main__": application.listen(8888) tornado.ioloop.IOLoop.instance().start()
Tornado处理用户请求的流程:
第一步:执行脚本,监听 8888 端口
第二步:浏览器客户端访问 /index --> http://127.0.0.1:8888/index
第三步:服务器接受请求,并交由对应的类处理该请求
第四步:类接受到请求之后,根据请求方式(post / get / delete ...)的不同调用并执行相应的方法
第五步:方法返回值的字符串内容发送浏览器
二、路由系统
路由系统其实就是URL和类的对应关系,这里不同于其他框架,其他框架均是URL对应函数,Tornado中每个URL对应的是一个类。
#!/usr/bin/env python # -*- coding:utf-8 -*- import tornado.ioloop import tornado.web class MainHandler(tornado.web.RequestHandler): def get(self): self.write("Hello, world") #self.write相当于django中的Httpresponse,还有self.render和self.redirect class StoryHandler(tornado.web.RequestHandler): def get(self, story_id): self.write("You requested the story " + story_id) class BuyHandler(tornado.web.RequestHandler): def get(self): self.write("buy.wupeiqi.com/index") application = tornado.web.Application([ (r"/index", MainHandler), (r"/story/([0-9]+)", StoryHandler), ]) application.add_handlers('buy.wupeiqi.com$', [ (r'/index',BuyHandler), ]) if __name__ == "__main__": application.listen(80) tornado.ioloop.IOLoop.instance().start()
三、模板
Tornado中的模板语言和Django中类似,模板引擎将模板文件载入内存,然后将数据嵌入其中,最终获取到一个完整的字符串,在将字符串返回给请求者。
Tornado的模板支持“控制语句”和“表达语句”,控制语句是使用“{% xx %}”包起来,例如{% if len(items) > 2 %}。表达语句是使用"{{ xx }}"包起来,如{{ items[0] }}.
控制语句和对应的Python语句的格式基本相同。支持if、for、while和try,这些语句逻辑结束的位置需要用{% end %}做标记。
还可以通过extends和block语句实现了模板继承。
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>老男孩</title>
<link href="{{static_url("css/common.css")}}" rel="stylesheet" /> 这样可以不加前缀,静态目录名如何变都行
{% block CSS %}{% end %}
</head>
<body>
<div class="pg-header">
</div>
{% block RenderBody %}{% end %}
<script src="{{static_url("js/jquery-1.8.2.min.js")}}"></script>
{% block JavaScript %}{% end %}
</body>
</html>