前言

Tornado是使用Python编写的一个强大的、可扩展的Web服务器。它在处理严峻的网络流量时表现得足够强健,但却在创建和编写时有着足够的轻量级,并能够被用在大量的应用和工具中。

Tornado是基于Bret Taylor和其他人员为FriendFeed所开发的网络服务框架,当FriendFeed被Facebook收购后得以开源。不同于那些最多只能达到10,000个并发连接的传统网络服务器,Tornado在设计之初就考虑到了性能因素,旨在解决C10K问题,这样的设计使得其成为一个拥有非常高性能的框架。此外,它还拥有处理安全性、用户验证、社交网络以及与外部服务(如数据库和网站API)进行异步交互的工具。

Tornado所做的是能够快速简单地编写高速的Web应用。如果编写一个可扩展的社交应用、实时分析引擎,或RESTful API,那么简单而强大的Python,以及Tornado正是为你准备的!

总之,Tornado也很强大!!!

下载和安装

# pip安装
pip3 install tornado
 
# 源码安装
tar xvzf tornado-4.4.1.tar.gz
cd tornado-4.4.1
python setup.py build
sudo python setup.py install

源码下载:tornado-1.2.1.tar.gz、 tornado-4.4.1.tar.gz

Tornado各模块

# 主要模块
    web        - FriendFeed 使用的基础 Web 框架,包含了 Tornado 的大多数重要的功能
    escape     - XHTML, JSON, URL 的编码/解码方法
    database   - 对 MySQLdb 的简单封装,使其更容易使用
    template   - 基于 Python 的 web 模板系统
    httpclient - 非阻塞式 HTTP 客户端,它被设计用来和 web 及 httpserver 协同工作
    auth       - 第三方认证的实现(包括 Google、Facebook、Yahoo BBAuth、FriendFeed...)
    locale     - 针对本地化和翻译的支持
    options    - 命令行和配置文件解析工具,针对服务器环境做了优化

# 底层模块
    httpserver - 服务于 web 模块的一个非常简单的 HTTP 服务器的实现
    iostream   - 对非阻塞式的 socket 的简单封装,以方便常用读写操作
    ioloop     - 核心的 I/O 循环

Hello,world

# 经典HelloWorld示例

import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")

application = tornado.web.Application([
    (r"/", MainHandler),
])

if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

路由系统

路由系统其实就是 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")
   
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中原生支持二级域名的路由,如:

Web框架系列之Tornado

方法

1、处理程序和参数

  请求来时,程序会用正则匹配相应路由地址,并交付于 tornado.web.RequestHandler 的子类处理;子类会根据请求方式(post / get / delete ...)的不同调用并执行相应的方法,方法返回字符串内容并发送到浏览器。

self.write("<h1>Hello, World</h1>")    # html代码直接写在浏览器客户端
self.render("index.html")              # 返回html文件,调用render_string(),内部其实是打开并读取文件,返回内容
self.redirect("http://www.baidu.com",permanent=False) # 跳转重定向,参数代表是否永久重定向

name = self.get_argument("name")       # 获取客户端传入的参数值
name = self.get_arguments("name")      # 获取多个值,类别形式
file = self.request.files["filename"]  # 获取客户端上传的文件

raise tornado.web.HTTPError(403)       # 返回错误信息给客户端

2、重写 RequestHandler 的方法函数

对于一个请求的处理过程代码调用次序如下:

  1. 程序为每一个请求创建一个 RequestHandler 对象;
  2. 程序调用 initialize() 函数,这个函数的参数是 Application 配置中的关键字参数定义。(initialize 方法是 Tornado 1.1 中新添加的,旧版本中你需要重写 __init__ 以达到同样的目的) initialize 方法一般只是把传入的参数存到成员变量中,而不会产生一些输出或者调用像 send_error 之类的方法。
  3. 程序调用 prepare()。无论使用了哪种 HTTP 方法,prepare 都会被调用到,因此这个方法通常会被定义在一个基类中,然后在子类中重用。prepare可以产生输出信息。如果它调用了finish(或send_error` 等函数),那么整个处理流程就此结束。
  4. 程序调用某个 HTTP 方法:例如 get()post()put() 等。如果 URL 的正则表达式模式中有分组匹配,那么相关匹配会作为参数传入方法。

 重写 initialize() 函数(会在创建RequestHandler对象后调用):

class ProfileHandler(tornado.web.RequestHandler):

    def initialize(self,database):
        self.database = database

    def get(self):
        self.write("result:" + self.database)

application = tornado.web.Application([
    (r"/init", ProfileHandler, dict(database="database"))
])

模板引擎

Tornao中的模板语言和django中类似,模板引擎将模板文件载入内存,然后将数据嵌入其中,最终获取到一个完整的字符串,再将字符串返回给请求者。

Tornado 的模板支持“控制语句”和“表达语句”,控制语句是使用 {% 和 %} 包起来的 例如 {% if len(items) > 2 %}。表达语句是使用 {{ 和 }} 包起来的,例如 {{ items[0] }}

控制语句和对应的 Python 语句的格式基本完全相同。我们支持 ifforwhile 和 try,这些语句逻辑结束的位置需要用 {% end %} 做标记。还通过 extends 和 block 语句实现了模板继承。这些在 template 模块 的代码文档中有着详细的描述。

注:在使用模板前需要在setting中设置模板路径:"template_path" : "tpl"

1、基本使用

#!/usr/bin/env python
# -*- coding:utf-8 -*-
  
import tornado.ioloop
import tornado.web
  
  
class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.render("index.html", list_info = [11,22,33])
  
application = tornado.web.Application([
    (r"/index", MainHandler),
])
  
  
if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()
app.py

相关文章: