tornado 杂记

一、建立一个简单的 hello world 网页

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

import tornado.ioloop

import tornado.web

class MainHandler( tornado.web.RequestHandler ):

    def get(self):

        self.write("Hello, world")

        return

settings = {

    "cookie_secret": "XmuwPAt8wHdnik4Xvc3GXmbXLifVmPZYhoc9Tx4x1iZ"

}

application = tornado.web.Application([

    (r"/", MainHandler)

    ],

    **settings

)

if __name__ == "__main__":

    application.listen(8090)

    tornado.ioloop.IOLoop.instance().start()

然后访问 http://localhost:8090/ 就可以访问最简单的网页了

具体的一些简单构建的细节在文档里说的很清楚,我就不累述了

tornado中文入门: http://www.tornadoweb.cn/

tornado中文文档: http://www.tornadoweb.cn/documentation

我主要想记载开发过程中遇到的一些比较技术性的东西

二、用户身份验证

1、一个简单的办法是,根据用户的IP

?


1

2

# 取得用户的IP地址

self.request.headers.get(‘X-Real-IP‘,self.request.remote_ip).decode("utf-8")

2、根据 cookie

上面这个办法当然太简陋了,另外一个办法是通过 cookies

首先要修改 settings

?


1

2

3

4

settings = {

    "cookie_secret": "XmuwPAt8wHdnik4Xvc3GXmbXLifVmPZYhoc9Tx4x123",

    "login_url": "/login"

}

指定一个加密 cookie 的 secret,再指定一个登陆跳转的页面,当未认证用户尝试登陆需要身份认证的页面的时候就会跳转到这一页面,一般习惯性用 /login

然后给 GET 或 POST 添加一个装饰器

?


1

2

3

4

5

class MainHandler( BaseHandler ):

    @tornado.web.authenticated

    def get(self):

        self.write("Hello, World")

        return

有了这个装饰器的网页就会要求用户认证身份,认证身份的方法也很简单,注意看 MainHandler 继承于 BaseHandler,这是我自己写的一个类

?


1

2

3

4

5

6

7

8

9

10

11

12

13

class BaseHandler(tornado.web.RequestHandler):

    def __init__( self, *args, **kwargs ):

        # 继承于 tornado.web.RequestHandler

        tornado.web.RequestHandler.__init__( self, *args, **kwargs )

        self.conn = DB()

        self.cursor = self.conn.cursor()

    # 这一方法就是 tornado 来判断用户是否已验证的方法

    # 改写这一方法。当返回 True 的时候,tornado就会认为用户已验证

    def get_current_user(self):

        # 我通过返回用户 cookie 的方式来判断是否已验证

        return self.get_secure_cookie("userid")

这时候你就需要有一个登陆页面了,你可以在里面放一个简单的 input 来输入账号密码,然后 POST 给服务器来进行验证,如果通过的话就存入 cookie

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

class Login( BaseHandler ):

def get(self):

    # 显示登陆页面,等待输入

def post(self):

  # 获取用户输入的账号密码

  userid = self.get_argument("userid", strip=True)

  password = self.get_argument("password", strip=True)

  # 对账号密码进行验证

  # 验证成功后存入cookie

  self.set_secure_cookie("userid", str(userid))

  # 这样用户就可以通过 BaseHandler 的检查了

三、静态文件夹

有时候需要用到一些静态文件夹,比如  js、css 和 ico 文件

可以通过在 settings 中增加设置来实现

?


1

2

3

4

5

6

7

8

9

10

11

settings = {

    # 设置静态文件夹,此处设置为了 ./static

    # 就可以直接访问 http://localhost:8090/static/* 的文件了

    "static_path": os.path.join(pwd, "static"),

    # 设置 cookie_secret

    "cookie_secret": "XmuwPAt8wHdnik4Xvc3GXmbXLifVmPZYhoc9Tx4x1iZ",

    # 设置登录页面

    "login_url": "/login",

    # 是否防跨域 POST (具体见文档)

    "xsrf_cookies": True

}

四:render 的时候将不该显示的 xsrf_form_html() 显示出来了

按照文档设置了 xsrf_cookies: True ,并且在 form 中添加了 {{ xsrf_form_html() }} 后,这条内容却被显示在了网页

这是因为 2.1 之后的 tornado 自动开启了escape,它会自动的将字符符号转义,有两种解决办法,一种是在 HTML 中改写成 {% raw xsrf_form_html() %} 来标明此条语句不转义,另外一种就是在 settings 中将自动转义关掉

?


1

2

3

4

5

6

7

8

settings = {

    "static_path": os.path.join(pwd, "static"),

    "cookie_secret": "XmuwPAt8wHdnik4Xvc3GXmbXLifVmPZYhoc9Tx4x1iZ",

    "login_url": "/login",

    "xsrf_cookies": True,

    # 关掉自动 escape

    "autoescape":None,

}

五、当 static 文件夹不在本地的时候

static_url 貌似只能解析本地的路径,如果部署在类似 SAE 这样的云平台的时候,代码服务器和存放文件的 Storage 服务器不在一个 domain 上时,static就没法工作了

我的解决办法是自己重写了 tornado.web.RequestHandler 中的 static_url 方法

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

class BaseHandler(tornado.web.RequestHandler):

    def __init__( self, *args, **kwargs ):

        tornado.web.RequestHandler.__init__( self, *args, **kwargs )

        self.conn = DB()

        self.cursor = self.conn.cursor()

    def get_current_user(self):

        return self.get_secure_cookie("userid")

    # 覆写 static_url 方法,让其解析到文件服务器的地址

    def static_url(self, path, include_host=None, **kwargs):

        self.require_setting("static_path", "static_url")

        base = "http://forecastexam-public.stor.sinaapp.com/static/"

        return base + path

六、异步操作

可以看看下面这几篇文章

看完这几篇应该大概明白了吧,tornado 是单线程的,要让单线程的效率达到最高,而且不因此而阻塞,最好的办法就是使用异步,异步说白了就是事件驱动,有事(触发)的时候就叫我(callback),没事的时候就 yield 挂着跑别的程序去,不阻塞主线程

tornado 自己带了一个异步的 httpclient ,所以最简单的办法就是把耗时操作单独拿出来放到另外一个 tornado 服务器里,然后用主服务器的 Asynchttpclient 去请求,等数据服务器处理好了返回数据触发 callback

上面的文章里提到了 celery,我没用过 celery,但是 Python 里最常用的异步就是 select 了吧,在 Windows 上只支持 socket,道理同上,把耗时操作放到另外的模块里,然后用 socket 通信传递数据。如果是 epoll 的话,还需要考虑是 level(状态触发) 还是 edge(边缘触发),这个是后话…(我也还在学习中

代码就不贴了,上面的例子里代码挺多了

时间: 2024-11-06 23:55:22

tornado 杂记的相关文章

微信小程序连接Tornado

自己搭建Tornado 监听8000端口, 提供给小程序访问的地址为http://127.0.0.1:8000/index #!/usr/bin/env python # -*- coding:utf-8 -*- import tornado.ioloop import tornado.web class MainHandler(tornado.web.RequestHandler): def get(self): print('GET方式请求成功') self.write("123"

深入tornado中的IOStream

IOStream对tornado的高效起了很大的作用,他封装了socket的非阻塞IO的读写操作.大体上可以这么说,当连接建立后,服务端与客户端的请求响应都是基于IOStream的,也就是说:IOStream是用来处理连接的. 接下来说一下有关接收请求的大体流程: 当连接建立,服务器端会产生一个对应该连接的socket,同时将该socket封装至IOStream实例中(这代表着IOStream的初始化). 我们知道tornado是基于IO多路复用的(就拿epoll来说),此时将socket进行r

Tornado Web 框架

一.简介 Tornado 是 FriendFeed 使用的可扩展的非阻塞式 web 服务器及其相关工具的开源版本.这个 Web 框架看起来有些像web.py 或者 Google 的 webapp,不过为了能有效利用非阻塞式服务器环境,这个 Web 框架还包含了一些相关有用工具及优化. Tornado 和现在的主流 Web 服务器框架(包括大多数 Python 的框架)有着明显的区别:它是非阻塞式服务器,而且速度相当快.得利于其非阻塞的方式和对 epoll 的运用,Tornado 每秒可以处理数以

Python框架之Tornado(二)请求阶段

概述 上图是tornado程序启动以及接收到客户端请求后的整个过程,对于整个过程可以分为两大部分: 启动程序阶段,又称为待请求阶段(上图1.2所有系列和3.0) 接收并处理客户端请求阶段(上图3系列) 简而言之: 1.在启动程序阶段,第一步,获取配置文件然后生成url映射(即:一个url对应一个XXRequestHandler,从而让XXRequestHandler来处理指定url发送的请求):第二步,创建服务器socket对象并添加到epoll中:第三步,创建无线循环去监听epoll. 2.在

tornado SSL3_READ_BYTES sslv3

////// ////// 支付宝回调,遇到问题 ////// WARNING:tornado.general:SSL Error on 9 ('110.75.248.125', 13675): [Errno 1] _ssl.c:504: error:14094416:SSL routines:SSL3_READ_BYTES:sslv3 alert certificate unknown ERROR:tornado.general:Uncaught exception Traceback (mo

tornado 资源

本章收集tornado(Python Web Framework)现有的资源 ##### introduction to tornado http://demo.pythoner.com/itt2zh/index.html document(tornadoweb) http://www.tornadoweb.org/en/stable/ http://www.tornadoweb.cn/documentation wiki(tornadoweb) https://github.com/torna

用 memcached 实现 Tornado 的 session 支持(一)

tornado 里面没有 session?不,当然有~我知道 github 上肯定有人帮我写好了~ O(∩_∩)O~ 于是乎,找到下面这个项目,用 memcached 实现 tornado 的 session.光会用可不行啊,让我们看看是怎么写的~ 项目地址:tornado-memcached-sessions 让我们先从 demo 看起.... app.py 中: 首先可以注意到,这里定义了一个新的 Application 类,继承于 tornado.web.Application, 在该类的

【从0开始Tornado建站】显示所有注册用户

显示注册用户的前台主要代码如下: {%block content%} <ul> {%for i in users%} <li><a href='/user/{{i[1]}}' class='text-success h4'>{{i[1]}}<small>({{i[3]}}星级)</small></a></li> {%end%} <br/> </ul> {%end%} 显示注册用户的后台代码如下: c

Tornado学习之异步原理

本文和大家分享的主要是Tornado 异步原理相关内容,一起来看看吧,希望对大家学习Tornado有所帮助. Tornado是什么? Tornado是一个用Python编写的异步HTTP服务器,同时也是一个web开发框架. Tornado 优秀的大并发处理能力得益于它的 web server 从底层开始就自己实现了一整套基于 epoll 的单线程异步架构. 同步.异步编程差异 .对于同步阻塞型Web服务器,我们来打个比方,将它比作一间饭馆,而Web请求就是来这家饭馆里吃饭的客人.假设饭馆店里只有