码迷,mamicode.com
首页 > 其他好文 > 详细

tornado

时间:2019-08-09 14:00:16      阅读:77      评论:0      收藏:0      [点我收藏+]

标签:hashlib   one   sock   from   dom   request   lan   逻辑   内容   

tornado

Tornado 是 FriendFeed 使用的可扩展的非阻塞式 web 服务器及其相关工具的开源版本。这个 Web 框架看起来有些像web.py 或者 Google 的 webapp,不过为了能有效利用非阻塞式服务器环境,这个 Web 框架还包含了一些相关的有用工具 和优化。

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

pip install tornado
源码安装
    https://pypi.python.org/packages/source/t/tornado/tornado-4.3.tar.gz

  一、快速上手

import tornado.ioloop
import tornado.web

# 视图
class MainHandler(tornado.web.RequestHandler):
def get(self):
d={"name":"yuan","l":[123,345,666],"info":{"name":"egon","age":"123"}}
self.render("templates/index.html",**d)

def post(self, *args, **kwargs):
pass

class LoginHandler(tornado.web.RequestHandler):
def get(self, *args, **kwargs):
self.render("templates/login.html")

def post(self, *args, **kwargs):
user=self.get_argument("user")
pwd=self.get_argument("pwd")
if user=="alex" and pwd=="123":
self.redirect("/index")
print("123ok")
else:
self.render("templates/login.html")

 

 

# 路由分配
application = tornado.web.Application([
(r"/index", MainHandler),
(r"/login", LoginHandler),
])

if __name__ == "__main__":
# 创建socket对象,bind listen
application.listen(8888)
# conn,addr=sock.accept()
tornado.ioloop.IOLoop.instance().start()

第一步:执行脚本,监听 8888 端口

第二步:浏览器客户端访问 /index  -->  http://127.0.0.1:8888/index

第三步:服务器接受请求,并交由对应的类处理该请求

第四步:类接受到请求之后,根据请求方式(post / get / delete ...)的不同调用并执行相应的方法

第五步:方法返回值的字符串内容发送浏览器

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 #!/usr/bin/env python
 4 # -*- coding:utf-8 -*-
 5 
 6 import tornado.ioloop
 7 import tornado.web
 8 from tornado import httpclient
 9 from tornado.web import asynchronous
10 from tornado import gen
11 
12 import uimodules as md
13 import uimethods as mt
14 
15 class MainHandler(tornado.web.RequestHandler):
16         @asynchronous
17         @gen.coroutine
18         def get(self):
19             print start get 
20             http = httpclient.AsyncHTTPClient()
21             http.fetch("http://127.0.0.1:8008/post/", self.callback)
22             self.write(end)
23 
24         def callback(self, response):
25             print response.body
26 
27 settings = {
28     template_path: template,
29     static_path: static,
30     static_url_prefix: /static/,
31     ui_methods: mt,
32     ui_modules: md,
33 }
34 
35 application = tornado.web.Application([
36     (r"/index", MainHandler),
37 ], **settings)
38 
39 
40 if __name__ == "__main__":
41     application.listen(8009)
42     tornado.ioloop.IOLoop.instance().start()

二、路由系统

路由系统其实就是 url 和 类 的对应关系,这里不同于其他框架,其他很多框架均是 url 对应 函数,Tornado中每个url对应的是一个类。

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

三、模板

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

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

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

技术图片
 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
 5     <title>tornado</title>
 6     <link href="{{static_url("css/common.css")}}" rel="stylesheet" />
 7     {% block CSS %}{% end %}
 8 </head>
 9 <body>
10 
11     <div class="pg-header">
12 
13     </div>
14     
15     {% block RenderBody %}{% end %}
16    
17     <script src="{{static_url("js/jquery-1.8.2.min.js")}}"></script>
18     
19     {% block JavaScript %}{% end %}
20 </body>
21 </html>
layout
技术图片
 1 {% extends layout.html%}
 2 {% block CSS %}
 3     <link href="{{static_url("css/index.css")}}" rel="stylesheet" />
 4 {% end %}
 5 
 6 {% block RenderBody %}
 7     <h1>Index</h1>
 8 
 9     <ul>
10     {%  for item in li %}
11         <li>{{item}}</li>
12     {% end %}
13     </ul>
14 
15 {% end %}
16 
17 {% block JavaScript %}
18     
19 {% end %}
index
import tornado.ioloop
import tornado.web
  
  
class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.render(home/index.html)
  
settings = {
    template_path: template,
}
  
application = tornado.web.Application([
    (r"/index", MainHandler),
], **settings)
  
  
if __name__ == "__main__":
    application.listen(80)
    tornado.ioloop.IOLoop.instance().start()

四、使用

import tornado.ioloop
import tornado.web

#视图
class MainHandle(tornado.web.RequestHandler):
    def initialize(self):
        print(123)  #在每一次请求开始先执行一下初始化这个方法
    def get(self):
        print(self.get_cookie(user))
        self.write(hello world)  #默认有个return none
    def post(self,*args,**kwargs):
        pass

class LoginHandle(tornado.web.RequestHandler):
    def get(self,*args,**kwargs):
        self.render(templates/login.html)  #没有脱离文件路径的知识
    def post(self,*args,**kwargs):
        user = self.get_argument(user)
        pwd = self.get_argument(pwd)
        print(user,pwd)
        if user==haiyan and pwd==123:
            self.set_cookie(user,haiyan,10) #设置cookie,10秒后过期
            self.set_secure_cookie(user,haiyan,) #签名cookie
            self.redirect(/index)  #要么return一下
        else:                      #要么else分割开,不然会报错
            self.render(templates/login.html)
        # self.get_arguments() #getlist 像是复选框,一下取多个值

class TestHandle(tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        sss = {name:"haiyan","info":{name:小华,age:18},"li":[11,22,33]}
        self.render(templates/test.html,**sss)

settings={
    static_path:static,
    xsrf_cookies:True,
    cookie_secret:1254
}
#路由分配
application = tornado.web.Application([
    (r/index,MainHandle),
    (r/login,LoginHandle),
    (r/test,TestHandle)
],**settings)

if __name__ == __main__:
    #创建socket对象,bind.listen
    application.listen(8080)
    # conn,addr = sock.accept

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

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width">
    <title>Title</title>
</head>
<body>
<h4>登录页面</h4>
<form action="" method="post">
{#    {{ xsrf_form_html() }}#}
    {% raw  xsrf_form_html() %}  原生的
    用户名:<input type="text" name="user">
    密码:<input type="password" name="pwd">
    <input type="submit" value="登录">
</form>
</body>
</html>

test.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width">
    <title>Title</title>
    <link rel="stylesheet" href="/static/test.css">  <!--用之前需要配置一下-->
</head>
<body>
<h1>{{ name }}</h1>
<h2>{{ info.get(age) }}</h2>
<h1>{{ info[name] }}</h1>
<h1>{{ li }}</h1>
<h1>{{ li[0] }}</h1>

==================循环生成=============
<ul>
    {% for i in li%}
    <li>{{ i }}</li>
    {% end %}
</ul>


</body>
</html>

五、自定义session

import tornado.ioloop
import tornado.web

#视图
from hashlib import sha1
import os
import time
create_session_id = lambda  :sha1(bytes(%s%s%(os.urandom(16),time.time()),encoding=‘‘)).hexdigest()
class SessionSix(object):
    session_cache = {  #一开是是NOne的      #开辟一个内存空间,保存这个人的状态
        # ‘sddfgfhsdsffd‘:{},
        # "sdfsdgfgd":{}
    }  #
    def __init__(self,handle):
        self.handle = handle
        #先获取session_id的值
        random_str = self.handle.get_cookie(_session_id)
        if not random_str:
            #如果没有随机字符串,说明是第一次登陆
            random_str = create_session_id()
            self.session_cache[random_str] = {}
        else:
            if random_str not in self.session_cache:#判断他的session_id和自己给它的session_id是否相等
                random_str = create_session_id()
                self.session_cache[random_str] = {}#你伪造了一个假的,我就认为你是第一次来
        self.random_str = random_str #来表示不同的用户对应的身份


    def __setitem__(self, key, value):
        self.session_cache[self.random_str][key] = value
        self.handle.set_cookie(_session_id,create_session_id())

    def __getitem__(self, item):
        return self.session_cache[self.random_str].get(item)

    def __delitem__(self, key):
        pass
class MainHandle(tornado.web.RequestHandler):
    def initialize(self):
        self.session = SessionSix(self)
    def get(self):
        print(self.session[user])  #获取session
        # print(self.get_cookie(‘user‘))
        self.write(hello world)  #默认有个return none
    def post(self,*args,**kwargs):
        pass

class LoginHandle(tornado.web.RequestHandler):
    def initialize(self):
        # print(‘123‘)  #在每一次请求开始先执行一下初始化这个方法
        self.session = SessionSix(self)
    def get(self,*args,**kwargs):
        self.render(templates/login.html)  #没有脱离文件路径的知识
    def post(self,*args,**kwargs):
        user = self.get_argument(user)
        pwd = self.get_argument(pwd)
        print(user,pwd)
        if user==haiyan and pwd==123:
            self.session[user] = 666  #设置自定义的session
            # self.set_cookie(‘user‘,‘haiyan‘,10) #设置cookie,10秒后过期
            # self.set_secure_cookie(‘user‘,‘haiyan‘,) #签名cookie
            self.redirect(/index)  #要么return一下
        else:                      #要么else分割开,不然会报错
            self.render(templates/login.html)
        # self.get_arguments() #getlist 像是复选框,一下取多个值

class TestHandle(tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        sss = {name:"haiyan","info":{name:小华,age:18},"li":[11,22,33]}
        self.render(templates/test.html,**sss)

settings={
    static_path:static,
    xsrf_cookies:True,
    cookie_secret:1254
}
#路由分配
application = tornado.web.Application([
    (r/index,MainHandle),
    (r/login,LoginHandle),
    (r/test,TestHandle)
],**settings)

if __name__ == __main__:
    #创建socket对象,bind.listen
    application.listen(8080)
    # conn,addr = sock.accept

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

 

tornado

标签:hashlib   one   sock   from   dom   request   lan   逻辑   内容   

原文地址:https://www.cnblogs.com/zcfx/p/11326380.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!