tornado源码阅读--开篇

Tornado是一款基于Python的高性能非阻塞Web服务器框架,源于FriendFeed的需求,用于实时Web服务。它支持高并发连接,尤其适合实时功能如聊天和推送通知。本文将介绍Tornado的架构、核心模块、请求处理、模板系统、用户认证、跨站请求防护及静态文件处理等关键特性。示例代码展示了如何设置路由、处理请求、使用模板和设置cookie。Tornado还提供了异步HTTP客户端和第三方认证支持,方便开发者构建实时Web应用。
摘要由CSDN通过智能技术生成
工作之中使用python也是有一段时间了,都是python有很多不错的网络框架,例如:Django、twisted、tornado、web.py、flask等等,
但是由于工作性质的关系,很多都没有用过,最近闲来无事,安装了一个tornado来学习学习,欢迎大家学习交流。废话不多说。首先还是从官方的文档开始吧。


概括

FriendFeed使用了一款使用 Python 编写的,相对简单的 非阻塞式 Web 服务器。其应用程序使用的 Web 框架看起来有些像 web.py 或者 Google 的 webapp, 不过为了能有效利用非阻塞式服务器环境,这个 Web 框架还包含了一些相关的有用工具 和优化。

Tornado 就是我们在 FriendFeed 的 Web 服务器及其常用工具的开源版本。Tornado 和现在的主流 Web 服务器框架(包括大多数 Python 的框架)有着明显的区别:它是非阻塞式服务器,而且速度相当快。得利于其 非阻塞的方式和对 epoll的运用,Tornado 每秒可以处理数以千计的连接,因此 Tornado 是实时 Web 服务的一个 理想框架。我们开发这个 Web 服务器的主要目的就是为了处理 FriendFeed 的实时功能 ——在 FriendFeed 的应用里每一个活动用户都会保持着一个服务器连接。

以下是经典的 “Hello, world” 示例:

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()

我们清理了 Tornado 的基础代码,减少了各模块之间的相互依存关系,所以理论上讲, 你可以在自己的项目中独立地使用任何模块,而不需要使用整个包。

模块索引

最重要的一个模块是web, 它就是包含了 Tornado 的大部分主要功能的 Web 框架。其它的模块都是工具性质的, 以便让 web 模块更加有用 后面的 Tornado 攻略 详细讲解了 web 模块的使用方法。

主要模块

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

底层模块

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

Tornado 攻略

请求处理程序和请求参数

Tornado 的 Web 程序会将 URL 或者 URL 范式映射到 tornado.web.RequestHandler 的子类上去。在其子类中定义了get() 或 post() 方法,用以处理不同的 HTTP 请求。

下面的代码将 URL 根目录 / 映射到 MainHandler,还将一个 URL 范式 /story/([0-9]+) 映射到 StoryHandler。正则表达式匹配的分组会作为参数引入 的相应方法中:

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("You requested the main page")

class StoryHandler(tornado.web.RequestHandler):
    def get(self, story_id):
        self.write("You requested the story " + story_id)

application = tornado.web.Application([
    (r"/", MainHandler),
    (r"/story/([0-9]+)", StoryHandler),
])

你可以使用 get_argument() 方法来获取查询字符串参数,以及解析 POST 的内容:

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write('<html><body><form action="/" method="post">'
                   '<input type="text" name="message">'
                   '<input type="submit" value="Submit">'
                   '</form></body></html>')

    def post(self):
        self.set_header("Content-Type", "text/plain")
        self.write("You wrote " + self.get_argument("message"))

上传的文件可以通过 self.request.files 访问到,该对象将名称(HTML元素 <input type="file">的 name 属性)对应到一个文件列表。每一个文件都以字典的形式 存在,其格式为 {"filename":..., "content_type":..., "body":...}

如果你想要返回一个错误信息给客户端,例如“403 unauthorized”,只需要抛出一个 tornado.web.HTTPError 异常:

if not self.user_is_logged_in():
    raise tornado.web.HTTPError(403)

请求处理程序可以通过 self.request 访问到代表当前请求的对象。该 HTTPRequest 对象包含了一些有用的属性,包括:

  • arguments - 所有的 GET 或 POST 的参数
  • files - 所有通过 multipart/form-data POST 请求上传的文件
  • path - 请求的路径( ? 之前的所有内容)
  • headers - 请求的开头信息

你可以通过查看源代码  httpserver 模组中  HTTPRequest 的定义,从而了解到它的 所有属性。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值