Tornado

Posted xzcvblogs

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Tornado相关的知识,希望对你有一定的参考价值。

1.Tornado简介

      Tornado是基于epoll的非阻塞式WEB框架,是一个轻量级的Web服务的开源软件

    1.1特点

      Tornado拥有异步非阻塞IO处理方式,其出色的负载能力,官方用nginx反向代理的方式部署的Tornado比其他框架更能抗压

    1.2使用场景

      可以用于开发用户量大,高并发,大量HTTP持久链接的WEB网站

    1.3性能

      Tornado在设计之初就考虑到了性能因素,旨在解决C10K问题,这样的设计使其成为一个拥有非常高性能的解决方案

2.Tornado的机制

   技术图片

 

 

   Tornado机制:

    1.先创建parse_command_line()函数,产生了一个app的对象

    2.启动的HttpServer的服务器,把app放进HttpServer中

    3.listen监听端口

    4.ioloop.IoLoop.currentc创建Socket服务,把socket服务放到epoll里面

    5.ioloop.IoLoop.current.start()启动服务,不断的访问epoll

    6.前端发送请求

    7.epoll监听的端口告诉socket,

              8.新建立一个socket

    9.然后socket访问(路由映射列表),进行解包,

    10.把数据返回给浏览器

  epoll和kqueue的区别如下:  

    kevent与epoll最大的不同在于READ/WRITE事件是分开注册并且分开返回的,而Epoll则是一个fd一次返回读和写事件,用标志位来判断。  

  详情:https://www.cnblogs.com/linganxiong/p/5583415.html

 

 

3.Tornado使用

3.1常用方法

import tornado.web   
import tornado.ioloop
import json
class IndexHandler(tornado.web.RequestHandler):

    def set_default_headers(self):
          #返回前端的请求头
            self.set_header("Content-Type","application/json")
  #get请求
    def get(self):
        # 输出在网页上
        self.write("ok")
     # 获取路由上的值,例如:http://127.0.0.1:8001/?subject=谢城
     subject=self.get_query_argument(‘subject‘)

     # 获取url上多个值,例如:?q=1&q=2&q=3
     query_args=self.get_query_arguments("q")

     # 获取url上最后一个值
     query_arg=self.get_query_argument("q") #返回unicode字符串
      #获取url上最后一个值
      body=self.get_argument("a")

      # 返回字符串类型的列表类型
      # strip=False可以让url的元素可以携带空格
      bodys=self.get_arguments("a",strip=False)
      print(self.request.files)
      ##重定向 self.redirect() 重定向跳转到其他页面,比如self.redirect("/write")跳转到http://127.0.0.1:9000/wtite
      ##接收错误,并处理。所以说上面这两个必须连用。 self.write_error(status_code,**kwargs) 接收返回来的错误并处理错误
      ##抛出HTTP错误状态码,默认为500, tornado会调用write_error()方法并处理 self.send_error(status_code=500,**kwargs) 抛出错误
     self.files:用户上传的文件,字典类型      
     ##设置状态码
     self.set_status(status_code,reason=None)
         作用:为响应设置状态码
          self.set_status(404,"bad boy")
        参数:status_code (状态码的值,int类型)
                    如果reason=None,则状态码必须为正常值,列如999
            reason (描述状态码的词组,sting字符串类型)
if __name__ == __main__: # 创建一个app对象
   #Application:他是tornado.web的核心应用类,是与服务器对应的一个接口,里面保存了路由映射表
   # 还有一个listen方法,可以认为用来创建一个http的实例,并绑定端口
app=tornado.web.Application( [ #设置Url (r/,IndexHandler) ]) # 绑定一个监听接口 app.listen(8000) # 启动web程序 tornado.ioloop.IOLoop.current().start() 启动127.0.0.1:8000

3.2reuqust对象

  1.request对象作用:
  储存了关于请求的相关信息
  2.属性:
  method:HTTP请求的方式
  host:被请求的主机名
  uri:请求的完整资源地址,包括路径和get查询参数部分
  path:请求的路径部分
  query:请求参数部分
  version:使用的HTTP版本
  headers:请求的协议头,字典类型
  body:请求体数据
  remote_ip:客户端的ip
  files:用户上传的文件,字典类型

 

3.3前后端交互

import json
import os

import tornado.web
import tornado.ioloop
import tornado.options
import tornado.httpserver

from tornado.web import RequestHandler,url,StaticFileHandler
from tornado.options import define,options
import tornado.ioloop

# 定义了服务器监听的默认端口
# define("post",default=8000,type=int)

# torando支持传输自定义函数
def title_join(number):
    return "_".join(number)


class IndexHandler(RequestHandler):
    def get(self):
        # 跳转模板
        # self.render("head.html",n=100,b=200)
        dic=[{"name":"谢城","age":18,"gender":""},{"name":"杨美","age":24,"gender":""}]
        self.render("exd.html",dic=dic,func=title_join)

class ItcastHandler(RequestHandler):
    def get(self):
        self.write(<h2>baidu</h2>)

if __name__ == __main__:
    tornado.options.parse_command_line()
    # 项目目录
    current_path=os.path.dirname(__file__)
    # 配置模板
    settings=dict(
        # 配置静态资源
        static_path=os.path.join(current_path, "static"),
        # 配置模板
        template_path=os.path.join(current_path, "template"),
        # 配置token
        xsrf_cookies=True,
    )


    # url
    app=tornado.web.Application([
        (r"/",IndexHandler),
        # 配置url
        # (r‘/itcast‘, ItcastHandler),
        # 配置静态页面
        (r/(.*), StaticFileHandler, {"path": os.path.join(current_path, "static"), "default_filename": red.html}),

    ],

        **settings)

    http_server=tornado.httpserver.HTTPServer(app)
    http_server.listen(8886)
    tornado.ioloop.IOLoop.current().start()

 

 3.4Tornado模板语言

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>Title</title>

</head>
<body>
<h1>天下第一</h1>
{%if len(dic)>0%}
{%for i in dic%}
<h4>{{i["name"]}}</h4>
<h4>{{i["age"]}}</h4>
<h4>{{i["gender"]}}</h4>

{{func(i["name"])}}

{%end%}
{%else%}
没有数据
{%end%}
{% block  js%} {% end %}
</body>
</html>

 

 4.Torando异步

  因为epollz主要是用来解决网络IO的并发问题,所以Tornado的异步编程主要体现再网络IO的异步上,即异步Web请求

   4.1tornado.httpclient.AsyncHTTPClient

    Tornado提供了一个异步Web请求客户端1tornado.httpclient.AsyncHTTPClient用来进行异步Web请求

    fetch(request,callback=None)

    用于执行一个web请求request,并异步返回一个tornado.httpclient.HTTPResponse响应

    request可以是一个url,也可以是一个tornado.httpclient.HTTPRequest对象,如果是Url,fetch会自己构造一个HttpRequest对象

 

   4.2回调异步

      未完待续

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

     

 

以上是关于Tornado的主要内容,如果未能解决你的问题,请参考以下文章

tornado v6 似乎已经放弃了 tornado.web.asynchronous 协程。在代码中解决这个问题有啥不同的方法吗?

源代码剖析tornado-memcached-sessions —— Tornado session 支持的实现

tornado服务器实现原理

1.Tornado简介&&本专栏搭建tornado项目简介

tornado 启动WSGI应用(Flask)使用多线程将同步代码变成异步

有没有一种好方法可以将 pychecker/pylint 应用于 Tornado 模板中的 python 代码?