精华内容
下载资源
问答
  • tornado框架
    2021-02-22 14:46:03
    from tornado.httpserver import HTTPServer
    from tornado.ioloop import IOLoop
    import tornado.web
    from handler import handler_recall_service
    
     
    os.environ['OMP_NUM_THREADS'] = "1"
    
    
    def multi_app():
        port = 9090
        app = tornado.web.Application(handlers=[
                  (r'/show/', 调用方法1),
                  (r'/content/', 调用方法2),
              ])
        http_server = HTTPServer(app)   #建立http服务
        http_server.bind(int(port))     #监听端口
        http_server.start(10)       #运行一个线程时开启几个进程
        IOLoop.instance().start()   #开启线程
    if __name__ == "__main__":
        multi_app()
    

     

    更多相关内容
  • Tornado框架基础

    2021-03-23 14:36:56
    这个Web框架看起来有些像web.py或者Google的webapp,不过为了能有效利用非阻塞式服务器环境,这个Web框架还包含了一些相关的有用工具和优 一、Tornado框架概述 Tornado是FriendFeed使用的可扩展的非阻塞式web服务器...
  • 所用拓展模块  xlrd:  Python语言中,读取Excel的扩展工具。可以实现指定表单、指定单元格的读取。  使用前须安装。 ... 解压后cd到解压目录,执行 python setup.py install 即可  datetime: ...
  • tornado即是一个http非阻塞服务器, 就要用起来, 我们将用到tornado框架 ,mongodb数据库 以及motor(mongodb的异步驱动).来简单实现tornado的非阻塞功能. 其他环境支持的下载与安装 1.安装mongodb $ sudo apt-get ...
  • 了解 Tornado 框架

    千次阅读 2022-04-18 12:37:44
    Tornado全称Tornado Web Server,是一个用Python语言写成的Web服务器兼Web应用框架,由FriendFeed公司在自己的网站FriendFeed中使用,被Facebook收购以后框架在2009年9月以开源软件形式开放给大众。 2、特点: 1...

    -------------------简介------------------- 
    1、概念: 
        Tornado全称Tornado Web Server,是一个用Python语言写成的Web服务器兼Web应用框架,由FriendFeed公司在自己的网站FriendFeed中使用,被Facebook收购以后框架在2009年9月以开源软件形式开放给大众。 

    2、特点: 
        1、作为Web框架,是一个轻量级的Web框架,类似于另一个Python web框架Web.py,其拥有异步非阻塞IO的处理方式。 

        2、作为Web服务器,Tornado有较为出色的抗负载能力,官方用nginx反向代理的方式部署Tornado和其它Python web应用框架进行对比,结果最大浏览量超过第二名近40%。 

    3、性能: 
        1、Tornado有着优异的性能。它试图解决C10k问题,即处理大于或等于一万的并发 

        2、Tornado框架和服务器一起组成一个WSGI的全栈替代品。单独在WSGI容器中也可以使用 

        3、tornado网络框架或者tornaod http服务器,有一定的局限性,为了最大化的利用 


    -------------------Tornado与Django的区别------------------- 
    1、Tornado 
        1、Tornado走的是少而精的方向,注重的是性能优越,它最出名的是异步非阻塞的设计方式。 

        2、特点: 
            1、HTTP服务器:Tornado框架和服务器一起组成一个WSGI的全栈替代品 

            2、异步编程 

            3、WebSockets 

    2、Django 
        1、Django是走大而全的方向,注重的是高效开发,它最出名的是其全自动化的管理后台:只需要使用起ORM,做简单的对象定义,它就能自动生成数据库结构、以及全功能的管理后台。 

        2、Django提供的方便,也意味着Django内置的ORM跟框架内的其他模块耦合程度高,应用程序必须使用Django内置的ORM,否则就不能享受到框架内提供的种种基于其ORM的便利。 

        3、特点: 
            1、session功能 

            2、后台管理 

            3、ORM 


    -------------------Tornado安装 
    1、查看工作环境中是否安装 
        $ pip list 

    2、安装对应的tornado环境 
        1、自动安装 
            $ pip install tornado 

        2、手动安装 
            1、下载安装包tornado-4.3.tar.gz(https://pypi.python.org/packages ... /tornado-4.3.tar.gz) 

            2、$ tar xvzf tornado-4.3.tar.gz 

            3、$ cd tornado-4.3 

            4、$ python setup.py build 

            5、$ sudo python setup.py install 

    3、安装对应的数据库操作环境 
        $ pip install trondb 


    -------------------Tornado基本模块 
    1、Tornado web 程序编写思路 
        1、创建web应用实例对象,第一个初始化参数为路由映射列表。 

        2、定义实现路由映射列表中的handler类。 

        3、创建服务器实例,绑定服务器端口。 

        4、启动当前线程的IOLoop。 

    2、tornado.web 
        1、RequestHandler: 
            封装了对应一个请求的所有信息和方法,write(响应信息)就是写响应信息的一个方法;对应每一种http请求方式(get、post等),把对应的处理逻辑写进同名的成员方法中(如对应get请求方式,就将对应的处理逻辑写在get()方法中),当没有对应请求方式的成员方法时,会返回“405: Method Not Allowed”错误。 

        2、Application: 
            Tornado Web框架的核心应用类,是与服务器对接的接口,里面保存了路由信息表,其初始化接收的第一个参数就是一个路由信息映射元组的列表;其listen(端口)方法用来创建一个http服务器实例,并绑定到给定端口(注意:此时服务器并未开启监听)。 

    3、tornado.ioloop 
        1、tornado的核心io循环模块,封装了Linux的epoll和BSD的kqueue,tornado高性能的基石 

        2、Linux的epoll原理图 

        3、IOLoop.current(): 
            返回当前线程的IOLoop实例。 

        4、IOLoop.start(): 
            启动IOLoop实例的I/O循环,同时服务器监听被打开。 

    4、tornado.httpserver 
        实例: 
            #coding:utf-8 
            #一个简单的Tornado web 

            #引用对应的Tornado包 
            from tornado.web import Application,RequestHandler 
            from tornado.ioloop import IOLoop 
            from tornado.httpserver import HTTPServer 

            class IndexHandler(RequestHandler): 

                def get(self): 

                    self.write('hello word!') 

            if __name__ == '__main__': 
                #创建一个app应用 
                app = Application([('/',IndexHandler)]) 

                #app.listen('8000') 
                #为应用创建一个http服务 
                http_server = HTTPServer(app) 

                #绑定对应的端口号 
                http_server.listen(8000) 

                #开启多个tornado进程 
                #http_server.bind(8000) 
                #http_server.start(4) 

                IOLoop.current().start() 

    5、tornado.options 
        1、tornado.options模块——全局参数定义、存储、转换。 

        2、tornado.options.define() 
            1、def define(name, default=None, type=None, help=None, metavar=None, 
               multiple=False, group=None, callback=None): 

            2、name 选项变量名,须保证全局唯一性,否则会报“Option 'xxx' already defined in ...”的错误; 

            3、default 选项变量的默认值,如不传默认为None; 

            4、type 选项变量的类型,从命令行或配置文件导入参数的时候tornado会根据这个类型转换输入的值,转换不成功时会报错,可以是str、float、int、datetime、timedelta中的某个,若未设置则根据default的值自动推断,若default也未设置,那么不再进行转换。可以通过利用设置type类型字段来过滤不正确的输入。 

            5、multiple 选项变量的值是否可以为多个,布尔类型,默认值为False,如果multiple为True,那么设置选项变量时值与值之间用英文逗号分隔,而选项变量则是一个list列表(若默认值和输入均未设置,则为空列表[])。 

            6、help 选项变量的帮助提示信息,在命令行启动tornado时,通过加入命令行参数 --help 可以查看所有选项变量的信息(注意,代码中需要加入tornado.options.parse_command_line())。 

        3、tornado.options.options 
            全局的options对象,所有定义的选项变量都会作为该对象的属性。 

        4、tornado.options.parse_command_line() 
            1、进行对应的初始化 

        5、tornado.options.parse_config_file(path) 

        6、实例 
          #coding:utf-8 
          #一个简单的Tornado web 

          #引用对应的Tornado包 
          from tornado.web import Application,RequestHandler 
          from tornado.ioloop import IOLoop 
          from tornado.httpserver import HTTPServer 
          import tornado.options 


          tornado.options.define("port",type=int,help="端口号") 

          class IndexHandler(RequestHandler): 

              def get(self): 

                  self.write('hello word!') 

          if __name__ == '__main__': 
              tornado.options.parse_command_line() 


              #创建一个app应用 
              app = Application([('/',IndexHandler)]) 

              #app.listen('8000') 
              #为应用创建一个http服务 
              http_server = HTTPServer(app) 

              #绑定对应的端口号 
              http_server.listen(tornado.options.options.port) 

              #开启多个tornado进程 
              #http_server.bind(8000) 
              #http_server.start(4) 

              IOLoop.current().start()

    展开全文
  • Tornado是一个异步的Python Web开发框架,同时也是一个优秀的异步服务器开发库,这里我们将来讲解一下Python的Tornado框架实现图片上传及图片大小修改功能方面的一些重点:
  • 主要介绍了简单介绍Python的Tornado框架中的协程异步实现原理,作者基于Python的生成器讲述了Tornado异步的特点,需要的朋友可以参考下
  • Tornado框架入门教程

    2021-07-20 09:18:16
    Tornado框架入门教程 Tornado在知乎广为使用,当你用Chrome打开网页版本的知乎,使用开发者工具仔细观察Network里面的请求,就会发现有一个特别的状态码为101的请求,它是用浏览器的websocket技术和后端服务器...

    Tornado框架入门教程

    Tornado在知乎广为使用,当你用Chrome打开网页版本的知乎,使用开发者工具仔细观察Network里面的请求,就会发现有一个特别的状态码为101的请求,它是用浏览器的websocket技术和后端服务器建立了长连接用来接收服务器主动推送过来的通知消息。这里的后端服务器使用的就是tornado服务器。Tornado服务器除了可以提供websocket服务外,还可以提供长连接服务,HTTP短链接服务,UDP服务等。Tornado服务器由facebook开源,在掌阅的后端也广为使用。

    这样一个强大的Tornado框架,究竟该如何使用,本文将带领读者循序渐进深入学习tornado作为web服务器的基础使用。

    import tornado.ioloop
    import tornado.web
     
    class MainHandler(tornado.web.RequestHandler):
        def get(self):
            self.write("Hello, world")
     
    def make_app():
        return tornado.web.Application([
            (r"/", MainHandler),
        ])
     
    if __name__ == "__main__":
        app = make_app()
        app.listen(8888)
        tornado.ioloop.IOLoop.current().start()
    

    这是官方提供了Hello, World实例,执行python hello.py,打开浏览器访问http://localhost:8888/就可以看到服务器的正常输出Hello, world

    一个普通的tornado web服务器通常由四大组件组成。

    1. ioloop实例,它是全局的tornado事件循环,是服务器的引擎核心,示例中tornado.ioloop.IOLoop.current()就是默认的tornado ioloop实例。
    2. app实例,它代表着一个完成的后端app,它会挂接一个服务端套接字端口对外提供服务。一个ioloop实例里面可以有多个app实例,示例中只有1个,实际上可以允许多个,不过一般几乎不会使用多个。
    3. handler类,它代表着业务逻辑,我们进行服务端开发时就是编写一堆一堆的handler用来服务客户端请求。
    4. 路由表,它将指定的url规则和handler挂接起来,形成一个路由映射表。当请求到来时,根据请求的访问url查询路由映射表来找到相应的业务handler。

    这四大组件的关系是,一个ioloop包含多个app(管理多个服务端口),一个app包含一个路由表,一个路由表包含多个handler。ioloop是服务的引擎核心,它是发动机,负责接收和响应客户端请求,负责驱动业务handler的运行,负责服务器内部定时任务的执行。

    当一个请求到来时,ioloop读取这个请求解包成一个http请求对象,找到该套接字上对应app的路由表,通过请求对象的url查询路由表中挂接的handler,然后执行handler。handler方法执行后一般会返回一个对象,ioloop负责将对象包装成http响应对象序列化发送给客户端。

    同一个ioloop实例运行在一个单线程环境下。

    阶乘服务

    下面我们编写一个正常的web服务器,它将提供阶乘服务。也就是帮我们计算n!的值。服务器会提供阶乘的缓存,已经计算过的就存起来,下次就不用重新计算了。使用Python的好处就是,我们不用当心阶乘的计算结果会溢出,Python的整数可以无限大。

    # fact.py
    import tornado.ioloop
    import tornado.web
     
     
    class FactorialService(object):  # 定义一个阶乘服务对象
     
        def __init__(self):
            self.cache = {}   # 用字典记录已经计算过的阶乘
     
        def calc(self, n):
            if n in self.cache:  # 如果有直接返回
                return self.cache[n]
            s = 1
            for i in range(1, n):
                s *= i
            self.cache[n] = s  # 缓存起来
            return s
     
     
    class FactorialHandler(tornado.web.RequestHandler):
     
        service = FactorialService()  # new出阶乘服务对象
     
        def get(self):
            n = int(self.get_argument("n"))  # 获取url的参数值
            self.write(str(self.service.calc(n)))  # 使用阶乘服务
     
     
    def make_app():
        return tornado.web.Application([
            (r"/fact", FactorialHandler),  # 注册路由
        ])
     
    if __name__ == "__main__":
        app = make_app()
        app.listen(8888)
        tornado.ioloop.IOLoop.current().start()
    

    执行python fact.py ,打开浏览器,键入http://localhost:8888/fact?n=50,可以看到浏览器输出了
    608281864034267560872252163321295376887552831379210240000000000,如果我们不提供n参数,访问http://localhost:8888/fact,可以看到浏览器输出了400: Bad Request,告诉你请求错误,也就是参数少了一个。

    使用Redis
    --
    上面的例子是将缓存存在本地内存中,如果换一个端口再其一个阶乘服务,通过这个新端口去访问的话,对于每个n,它都需要重新计算一遍,因为本地内存是无法跨进程跨机器共享的。

    所以这个例子,我们将使用Redis来缓存计算结果,这样就可以完全避免重复计算。另外我们将不在返回纯文本,而是返回一个json,同时在响应里增加字段来说名本次计算来源于缓存还是事实计算出来的。另外我们提供默认参数,如果客户端没有提供n,那就默认n=1。

    import json
    import redis
    import tornado.ioloop
    import tornado.web
     
     
    class FactorialService(object):
     
        def __init__(self):
            self.cache = redis.StrictRedis("localhost", 6379)  # 缓存换成redis了
            self.key = "factorials"
     
        def calc(self, n):
            s = self.cache.hget(self.key, str(n))  # 用hash结构保存计算结果
            if s:
                return int(s), True
            s = 1
            for i in range(1, n):
                s *= i
            self.cache.hset(self.key, str(n), str(s))  # 保存结果
            return s, False
     
     
    class FactorialHandler(tornado.web.RequestHandler):
     
        service = FactorialService()
     
        def get(self):
            n = int(self.get_argument("n") or 1)  # 参数默认值
            fact, cached = self.service.calc(n)
            result = {
                "n": n,
                "fact": fact,
                "cached": cached
            }
            self.set_header("Content-Type", "application/json; charset=UTF-8")
            self.write(json.dumps(result))
     
     
    def make_app():
        return tornado.web.Application([
            (r"/fact", FactorialHandler),
        ])
     
    if __name__ == "__main__":
        app = make_app()
        app.listen(8888)
        tornado.ioloop.IOLoop.current().start()
    

    当我们再次访问http://localhost:8888/fact?n=50,可以看到浏览器输出如下
    {"cached": false, "fact": 608281864034267560872252163321295376887552831379210240000000000, "n": 50}
    ,再刷新一下,浏览器输出{"cached": true, "fact": 608281864034267560872252163321295376887552831379210240000000000, "n": 50},可以看到cached字段由true编程了false,表明缓存确实已经保存了计算的结果。我们重启一下进程,
    再次访问这个连接,观察浏览器输出,可以发现结果的cached依旧等于true。说明缓存结果不再是存在本地内存中了。

    圆周率计算服务
    --
    接下来我们再增加一个服务,计算圆周率,圆周率的计算公式有很多种,我们用它最简单的。

    我们在服务里提供一个参数n,作为圆周率的精度指标,n越大,圆周率计算越准确,同样我们也将计算结果缓存到Redis服务器中,避免重复计算。

    # pi.py
    import json
    import math
    import redis
    import tornado.ioloop
    import tornado.web
     
    class FactorialService(object):
     
        def __init__(self, cache):
            self.cache = cache
            self.key = "factorials"
     
        def calc(self, n):
            s = self.cache.hget(self.key, str(n))
            if s:
                return int(s), True
            s = 1
            for i in range(1, n):
                s *= i
            self.cache.hset(self.key, str(n), str(s))
            return s, False
     
    class PiService(object):
     
        def __init__(self, cache):
            self.cache = cache
            self.key = "pis"
     
        def calc(self, n):
            s = self.cache.hget(self.key, str(n))
            if s:
                return float(s), True
            s = 0.0
            for i in range(n):
                s += 1.0/(2*i+1)/(2*i+1)
            s = math.sqrt(s*8)
            self.cache.hset(self.key, str(n), str(s))
            return s, False
     
    class FactorialHandler(tornado.web.RequestHandler):
     
        def initialize(self, factorial):
            self.factorial = factorial
     
        def get(self):
            n = int(self.get_argument("n") or 1)
            fact, cached = self.factorial.calc(n)
            result = {
                "n": n,
                "fact": fact,
                "cached": cached
            }
            self.set_header("Content-Type", "application/json; charset=UTF-8")
            self.write(json.dumps(result))
     
    class PiHandler(tornado.web.RequestHandler):
     
        def initialize(self, pi):
            self.pi = pi
     
        def get(self):
            n = int(self.get_argument("n") or 1)
            pi, cached = self.pi.calc(n)
            result = {
                "n": n,
                "pi": pi,
                "cached": cached
            }
            self.set_header("Content-Type", "application/json; charset=UTF-8")
            self.write(json.dumps(result))
     
    def make_app():
        cache = redis.StrictRedis("localhost", 6379)
        factorial = FactorialService(cache)
        pi = PiService(cache)
        return tornado.web.Application([
            (r"/fact", FactorialHandler, {"factorial": factorial}),
            (r"/pi", PiHandler, {"pi": pi}),
        ])
     
    if __name__ == "__main__":
        app = make_app()
        app.listen(8888)
        tornado.ioloop.IOLoop.current().start()
    

    因为两个Handler都需要用到redis,所以我们将redis单独抽出来,通过参数传递进去。另外Handler可以通过initialize函数传递参数,在注册路由的时候提供一个字典就可以传递任意参数了,字典的key要和参数名称对应。我们运行python pi.py,打开浏览器访问http://localhost:8888/pi?n=200,可以看到浏览器输出{"cached": false, "pi": 3.1412743276, "n": 1000},这个值已经非常接近圆周率了。

    转载至:https://zhuanlan.zhihu.com/p/37382503

    展开全文
  • Tornado框架学习

    2021-09-30 21:09:20
    目录 底层原理 select epoll 运行机制 Tornado中的Ioloop模块的作用 获取请求方式 文件上传与展示 通过请求头信息的判断来进行反爬验证 注册功能demo 重定向 用户登录 以及自己设置的错误界面跳转 Cookie Tornado ...

    目录

    底层原理

    select epoll 运行机制

    Tornado中的Ioloop模块的作用

    获取请求方式

    文件上传与展示

    通过请求头信息的判断来进行反爬验证

    注册功能demo

    重定向

    用户登录 以及自己设置的错误界面跳转

    Tornado 异步服务器端方式

    客户端异步请求


    Tornado基于epoll,ioloop中运行epoll机制

    更好的支持高并发,建立更多的服务器连接

    底层原理

     IO多路复用

    IO多路复用支持三种方式:select,poll,epoll

    windows\Mac:select

    linux:三种都支持

    select:最多只能有1024个连接

    epoll:连接没有上限

    poll是过渡产物

    select epoll 运行机制

    ioloop中有多个socket对象(绑定了IP地址和端口号)

    select不断轮询所有socket对象(无论对象处于什么状态),直到有socket对象达到就绪状态

    epoll只会询问所有socket对象一次,并给所有socket对象绑定监听函数,当要建立连接的时候,当某个socket对象达到就绪状态时,回调函数会通知用户,然后建立连接。

     另外,当处理类中有堵塞时,直接响应状态,不返回结果,由协程继续执行其他的响应。

    Tornado中的Ioloop模块的作用

    ioloop就是对I/O多路复用的封装,它实现了一个单例,将这个单例保存在IOLoop._instance中

    ioloop实现了Reactor模型,将所有要处理的I/O事件注册到一个中心I/O多路复用器上,同时主线程/进程阻塞在多路复用器上;一旦有I/O事件到来或是准备就绪(文件描述符或socket可读、写),多路复用器返回并将事先注册的相应I/O事件分发到对应的处理器中。

    另外,ioloop还被用来集中运行回调函数以及集中处理定时任务。

    学习链接

    获取请求方式

    get post中使用的方法

    import tornado.web
    import tornado.ioloop
    
    
    class IndexHandler(tornado.web.RequestHandler):
        def get(self, *args, **kwargs):
            self.render('templates/login.html')
    
    
    class LoginHandler(tornado.web.RequestHandler):
        def get(self, *args, **kwargs):
            # 取参数为html中的属性值
            # get_arguments 取多个属性值 value属性值不同时使用
            uname = self.get_argument('uname')
    
            # get_query_xx只适用于get 请求
            pwd = self.get_query_argument('pwd')
            print(uname, pwd)
            self.write(uname + ',' + pwd)
    
        def post(self, *args, **kwargs):
            uname = self.get_body_argument('uname')
            print(uname)
            self.write(uname)
    
    
    app = tornado.web.Application([(r'^/$', IndexHandler),
                                   (r'^/login/$', LoginHandler), ])
    
    app.listen(8888)
    
    tornado.ioloop.IOLoop.current().start()
    

    文件上传与展示

    import tornado.web
    import tornado.ioloop
    
    
    class UploadHandler(tornado.web.RequestHandler):
        def get(self, *args, **kwargs):
            self.render('templates/upload.html')
    
        def post(self, *args, **kwargs):
            # 获取上传的文件
            # 获取的数据 [{'body':b'\0\xff\xxx',"content_type":"image/jpeg,"filename":l.jpg}]
            img1 = self.request.files['img1']
    
            # 遍历 img1
            for img in img1:
                body = img.get('body', '')
                content_type = img.get('content_type', '')
                filename = img.get('filename', '')
            # 将图片存到files目录中
            import os
            dir = os.path.join(os.getcwd(), "files", filename)
            with open(dir, 'wb') as fw:
                fw.write(body)
    
            # 将图片显示到浏览器页面中
            # 设置响应头信息
            self.set_header('Content-Type', content_type)
            self.write(body)
    
    
    app = tornado.web.Application([(r'/upload/', UploadHandler)])
    
    app.listen(8888)
    
    tornado.ioloop.IOLoop.instance().start()
    

    通过请求头信息的判断来进行反爬验证

    import tornado.ioloop
    import tornado.web
    
    user_agents = [
        "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Mobile Safari/537.36"
    ]
    
    
    # 工具类,检测请求
    class RequestTools:
        class UaCheck:
    
            def __new__(cls, func):
                # 1 引入要装饰的类的类对象以及类函数 
                # 然后返回inner方法在inner方法中调用被装饰的类的类函数
                cls.func = func
                return cls.inner
    
            @staticmethod
            def check(handler):
                # 2 定义检测函数
                return handler.request.headers["User-Agent"]
    
            @staticmethod
            def inner(handler):
                # 3 运行检测方法 如果检测失败则返回UA错误,如果检测没问题则继续运行原类实例方法
                if not __class__.check(handler):
                    handler.write("UA错误")
                else:
                    return __class__.func(handler)
    
        class FrequencyCheck:
            ip_count = {}
    
            def __new__(cls, func):
                cls.func = func
                return cls.inner
    
            @staticmethod
            def check(handler):
                ip = handler.request.remote_ip
                num = __class__.ip_count.get(ip, 0) + 1
                __class__.ip_count[ip] = num
                return __class__.ip_count[ip] > 3
    
            @staticmethod
            def inner(handler):
                if __class__.check(handler):
                    handler.write("请求频率过高")
                else:
                    return __class__.func(handler)
    
    
    class LoginHandler(tornado.web.RequestHandler):
        # 加检测功能
        @RequestTools.UaCheck
        @RequestTools.FrequencyCheck
        def get(self):
            self.write("GET")
    
    
    # 业务类
    app = tornado.web.Application(
        [
            (r'^/$', LoginHandler)
        ]
    )
    
    # 第二个参数可传本机ip,否则默认127.0.0.1
    app.listen(8887, "localhost")
    
    tornado.ioloop.IOLoop.current().start()
    

    注册功能demo

    import tornado.web
    import tornado.ioloop
    import MySQLdb
    
    
    def _getConn():
        return MySQLdb.connect("localhost", "root", "123zx000", db="Tornado", port=3306)
    
    
    class RegisterHandler(tornado.web.RequestHandler):
        def initialize(self, conn):
            self.conn = conn
            print(conn)
    
        def get(self, *args, **kwargs):
            self.render('templates/register.html')
    
        def post(self, *args, **kwargs):
            # 获得请求参数
            uname = self.get_argument('uname')
            pwd = self.get_argument('pwd')
            # 将数据插入到数据库中
            try:
                cursor = self.conn.cursor()
                cursor.execute('insert into t_auth values(null,"%s","%s",now())' % (uname, pwd))
                self.conn.commit()
                self.write("注册成功")
            except:
                # 数据库回滚
                self.conn.rollback()
                self.redirect('/register/')
    
    
    # 数据库连接对象放在此处 会自动传递给 initialize方法中的conn
    app = tornado.web.Application([(r'^/register/$', RegisterHandler, {"conn": _getConn()})])
    app.listen(8888)
    
    tornado.ioloop.IOLoop.instance().start()
    

    重定向

    客户端发出请求,服务器给客户端一个返回的ip地址和302状态码

    客户端再向访问新ip地址

    import tornado.web
    from tornado.web import RedirectHandler
    import tornado.ioloop
    
    
    class IndexHandler(tornado.web.RequestHandler):
    
        def get(self, *args, **kwargs):
            # 第一种方法 重定向 302
            # self.redirect('https://www.baidu.com')
    
            # 方法2
            self.set_status(301)
            self.set_header("Location", "https://www.jd.com")
    
    
    app = tornado.web.Application(
        [(r'^/1/$', IndexHandler),
         # 方法3
         (r'^/red3/$', RedirectHandler, {"url": "https://www.taobao.com"}), ])
    app.listen(8889)
    
    tornado.ioloop.IOLoop.instance().start()
    

    用户登录 以及自己设置的错误界面跳转

    import tornado.web
    import tornado.ioloop
    import MySQLdb
    
    
    class LoginHandler(tornado.web.RequestHandler):
        def initialize(self, conn):
            self.conn = conn
    
        # 收到请求 就会执行此方法 可接收参数
        def prepare(self):
            # 判断当前请求方式
            if self.request.method == "POST":
                # 获取请求参数
                self.uname = self.get_argument("uname")
                self.pwd = self.get_argument("pwd")
            print()
    
        def get(self, *args, **kwargs):
            # print(1)
            self.render("templates/login.html")
    
        def post(self, *args, **kwargs):
            1 / 0
            cursor = self.conn.cursor()
            cursor.execute('select * from t_auth where uname="%s" and pwd="%s"' % (self.uname, self.pwd))
            user = cursor.fetchone()
            print(user)
            if user:
                self.write(u"登录成功")
            else:
                self.write(u"登录失败")
    
        # 如果访问遇到错误,跳转到指定的错误页面
        def write_error(self, status_code, **kwargs):
            self.render('templates/error.html')
        
        # 设置服务器信息
        def set_default_headers(self):
            self.set_header('Server', 'SXTServer')
    
    
    settings = {'debug': True}
    dbconfig = {
        'host': '127.0.0.1', 'user': 'root',
        'password': "123zx000", 'db': 'Tornado', "port": 3306}
    app = tornado.web.Application(
        [(r'^/login/$', LoginHandler, {'conn': MySQLdb.connect(**dbconfig)}),
         ], **settings)
    app.listen(8887)
    
    tornado.ioloop.IOLoop.instance().start()
    

    遇到bug 加了expire 设置cookie后无法获取 

    import tornado.web
    import tornado.ioloop
    
    
    class SetCookieHandler(tornado.web.RequestHandler):
        def get(self, *args, **kwargs):
            self.set_secure_cookie("name", "zhangsan")
            # self.set_cookie("hello", "zhangsan")
    
    
    class GetCookieHandler(tornado.web.RequestHandler):
        def get(self, *args, **kwargs):
            print(self.request.cookies)
            # name = self.get_cookie("hello")
    
            name = self.get_secure_cookie("name")
            self.write(name)
    
    
    # 加密
    settings = {"cookie_secret": "abcdefg"}
    
    app = tornado.web.Application([
        (r'^/$', SetCookieHandler),
        (r'/getCookie/$', GetCookieHandler)], **settings)
    
    app.listen(8886)
    
    tornado.ioloop.IOLoop.instance().start()
    

    Tornado 异步服务器端方式

    Tornado 6.0之前支持asynchronous  之后只支持coroutine(协程)

    import os
    
    from tornado.concurrent import Future
    from tornado.gen import coroutine
    from tornado.web import RequestHandler, Application
    from tornado.ioloop import IOLoop
    
    
    class IndexHandler(RequestHandler):
    
        @coroutine
        def get(self, filename):
            
            # 把耗时的操作交给回调函数进行异步处理
            content = yield self.readImg(filename)
    
            if not content:
                self.write_error(404)
            else:
                self.set_header("Content-Type", 'image/png')
                self.write(content)
    
        def readImg(self, filename):
            BaseDir = os.path.join(os.getcwd(), 'static', filename)
            print(BaseDir)
            with open(BaseDir, 'rb') as fr:
                content = fr.read()
    
            # 相当于生成器中的send方法,设定上一次的yield语句返回的值
            future = Future()
            future.set_result(content)
    
            return future
    
    
    app = Application([(r'^/static/(.*)$', IndexHandler)])
    
    app.listen(8000)
    
    IOLoop.instance().start()
    

    客户端异步请求

    可能是版本更改导致 

    asyncClient.fetch(url, callback) 未正常使用
    import os
    
    from tornado.httpclient import AsyncHTTPClient
    from tornado.ioloop import IOLoop
    
    
    # 在控制台打印页面信息
    def parse(con):
        import bs4
        bs = bs4.BeautifulSoup(con, 'html.parser')
        h4List = [h4.text for h4 in bs.select('ul.foot_nav.main h4')]
        for h in h4List:
            print(h)
    
    
    def handle_response(response):
        # 获取页面内容
        # print(221)
        content = response.body()
        # print(content)
        # 写入到index.html页面中
        with open(os.path.join(os.getcwd(), 'templates', 'index.html'), 'wb') as fw:
            fw.write(content)
    
        # 解析文档信息打印相关内容到控制台
        parse(content)
    
    
    def loadPage(url, callback):
        # 创建异步客户端
        asyncClient = AsyncHTTPClient()
        # 获取页面内容
        asyncClient.fetch(url, callback)
        # print(1111)
    
    
    loadPage('http://www.bjsxt.com', handle_response)
    
    IOLoop.instance().start()
    

    Websocket 的demo

    from tornado.web import RequestHandler, Application
    from tornado.ioloop import IOLoop
    from tornado.websocket import WebSocketHandler
    import os
    
    
    class IndexHander(RequestHandler):
        def get(self, *args, **kwargs):
            self.render('index.html')
    
    
    class SockHandler(WebSocketHandler):
        def open(self, *args, **kwargs):
            print(u'建立服务器连接')
    
        def on_message(self, message):
            print(u'收到客户端的消息:%s' % message)
            self.write_message('hello client')
    
        def on_close(self):
            print(u'断开服务器连接')
    
        # 允许跨域请求
        def check_origin(self, origin):
            return True
    
    
    app = Application([(r'^/$', IndexHander),
                       (r'^/websocket/$', SockHandler)], template_path=os.path.join(os.getcwd(), "templates"))
    
    app.listen(8001)
    
    IOLoop.instance().start()
    

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script type="text/javascript" src="https://cdn.staticfile.org/jquery/1.9.1/jquery.min.js"></script>
    </head>
    <body>
        <input type="button" onclick="send();" value="发送"/>
        <input type="button" onclick="closeSocket();" value="断开连接"/>
    
    
        <script>
            // 建立连接
            var ws = new WebSocket('ws://127.0.0.1:8001/websocket/');
    
            ws.onopen = function () {
                console.log("建立客户端连接");
            }
            // 输出 服务器发给客户端的消息
            ws.onmessage = function (evt) {
                console.log('收到服务器端消息:' + evt.data);
            }
            // 关闭连接
            ws.onclose = function (p1) {
                console.log("正在断开连接");
            }
    
            function send() {
                ws.send('你好,服务器端');
            }
            function closeSocket(){
                ws.close()
            }
        </script>
    
    </body>
    </html>

    据目前的理解,tornado框架的异步非堵塞的实现主要依赖于ioloop模块,此模块中主要是epoll机制 操作支持asyncio异步,下面是asyncio的介绍

    我的大略理解:归根结底,python还是一个线程来执行任务,是用协程来实现的高并发,如遇到耗时操作,主线程并未等待,而是去执行EventLoop(循环队列)中其他可以执行的coroutine(协程任务)了,因此可以实现并发执行。

    asyncio提供了完善的异步IO支持;

    异步操作需要在coroutine中通过yield from完成;

    多个coroutine可以封装成一组Task然后并发执行。

    asyncio学习链接

    学习链接:

    知乎Tornado

    Tornado框架

    展开全文
  • Tornado框架

    2021-04-29 18:20:14
    Tornado的学习 今天是2021年4月29号,马上就到了五一小长假了,这也是我学习tornado的第二周,相比较之前用的Djangoo。tornado比较复杂(仅是我...由于我用的是tornado框架,用python2开发,所以我也去了解了一下py
  • 首先,为什么选择Tornado: 1.高性能的网络库,这可以和gevent,twisted,libevent等做对。 提供了异步io支持,超时事件处理,在此基础上提供了tcpserver,httpclient,尤其是curlhttpclient, 在现有http客户端中肯定排...
  • Python 的 Tornado 框架,属于 Python 的一个 Web 框架,是由 Python 编写的 Web 服务器兼 Web 应用框架。 Step1:Tornado 是什么 Tornado 是一个基于 Python 的 Web 服务框架和异步网络库。 最早开发于 ...
  • 可扩展的非阻塞式Tornado框架基础.Tornado是FriendFeed使用的可扩展的非阻塞式web服务器及其相关工具的开源版本。这个Web框架看起来有些像web.py或者Google的webapp,不过为了能有效利用非阻塞式服务器环境,这个Web...
  • Tornado框架简介

    2019-12-17 15:33:49
    -------------------简介-------------------1、概念: Tornado全称Tornado Web Server,是一个用Python语言写成的Web服务器兼Web应用框架,由FriendFeed公司在自己的网站FriendFeed中使用,被Facebook收购以后框架...
  • tornado框架5分钟快速上手、tornado基础

    千次阅读 热门讨论 2021-01-11 16:49:56
    Python的Web框架种类繁多(比Python语言的关键字还要多),但在众多优秀的Web框架中,Tornado框架最适合用来开发需要处理长连接和应对高并发的Web应用。Tornado框架在设计之初就考虑到性能问题,它可以处理大量的...
  • Tornado框架中文手册

    2022-01-04 18:28:05
    Tornado中文版手册
  • 一、Tornado框架概述  Tornado 是 FriendFeed 使用的可扩展的非阻塞式 web 服务器及其相关工具的开源版本。这个 Web 框架看起来有些像 web.py 或者 Google 的 webapp,不过为了能有效利用非阻塞式服务器环境,这...
  • 基于Tornado框架实现的一套定时任务系统,完全兼容Linux Crontab支持到秒级 定时任务特点 restful api 简单易定制 可接入可视化界面操作 定时任务统一管理 完全兼容 crontab 支持秒级定时任务 任务可搜索、暂停、...
  • Tornado 是一款非阻塞可扩展的使用Python编写的web服务器和Python Web框架, 可以使用Tornado编写Web程序并不依赖任何web服务器直接提供高效的web服务.所以Tornado不仅仅是一个web框架而且还是一款可以用于生产环境的...
  • 基于Tornado框架的Python / HTML钱包。 第一个稳定发行版,仍在继续进行中,但可用且外观漂亮! 第一个稳定版本0.1.19 目标是在后台繁重地使用现有的python代码,但利用HTML / JS的GUI灵​​活性。 第一版具有...
  • Tornado框架简述

    2021-03-12 15:31:58
    安装tornado框架 pip install tornado==6.0.4 完成代码解析+注释 创建tornado????️项目 """ 导入模块 tornado.web 负责应用程序的开发 tornado.ioloop 负责服务启动 app = tornado.web.Application( [ 为了防止...
  • Tornado框架async异步调用数据库 – 潘登同学的Tornado学习笔记 文章目录Tornado框架async异步调用数据库 -- 潘登同学的Tornado学习笔记环境搭建异步操作数据库使用aiomysql进行增查改操作ORM--peewee的使用使用方法...
  • tornado框架demo

    2018-11-14 15:46:47
    tornado整个框架,按照企业开发的模式划分好层次,实现对mysql数据库的增删查改,登录注册功能。
  • 高性能服务器Tornado Python的web框架名目繁多,各有千秋。正如光荣属于希腊,伟大属于罗马。Python的优雅结合WSGI的设计,让web框架接口实现千秋一统。WSGI 把应用(Application)和服务器(Server)结合起来。...
  • 实习手册(基于Tornado框架的接口响应服务)基于tornado框架的简单服务的部署,tornado包的下载与安装
  • Tornado是一个python的开源web框架,它比django要轻量级到多,也没有什么组件,只有运用到对应到业务场景下我才使用这个框架,它是单进程单线程到异步非阻塞模型,适用与长连接长轮巡,高并发,异步非阻塞 ...
  • Tornado是一个Python web框架,也是异步网络库,通过使用非双向IO,它可以轻松处理C10K问题,对于长替换,WebSocket等长链接的开发,也比较容易。 目录结构 tornado作为web框架和异步网络库,代码量过多,因此在分析...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 19,101
精华内容 7,640
关键字:

tornado框架

友情链接: mysql.rar