• Tornado模块


    Tornado

    一个轻量级的Web框架

    简介

    1.Tornado在设计之初就考虑到了性能因素,旨在解决C10K问题,这样的设计使得其成为一个拥有非常高性能的框架。
    此外,它还拥有处理安全性、用户验证、社交网络以及与外部服务(如数据库和网站API等)进行交互的工具

    2.Tornado主要解决高并发问题,在处理高并发上,它采用异步的方式,通常能支持高于10K的并发

     

    tornado安装

    1 pip install tornado

    简单实用代码示例

    # -*- coding: utf-8 -*-
    __author__ = 'CQ'
    
    import textwrap
    import tornado.httpserver
    import tornado.ioloop
    import tornado.options
    import tornado.web
    import torndb
    import os
    from Tornado import databases_share  # 自定义功能更强大的SQL操作
    
    from tornado.options import define, options
    
    define("port", default=8888, help="run on the given port", type=int)
    
    
    def use_database():
        """
            使用tornado原生的SQL模块
        :return:
        """
        db = torndb.Connection(host="127.0.0.1", database="test", user="root", password="123456")
        a = db.get('select * from node where id=5 ')   # get 只能返回一行数据,且是字典格式,返回多行将报错
        print(a)
    
        b = db.query('select * from node')   # query 返回是列表格式的数据,能够返回多条,且每个列表项是一个字典
        print(b)
    
        exec_str = "insert into user(name,age,gender) values ('%s','%s','%s')" % ("张三", "58", "")
        res = db.execute(exec_str)
        print(res)
    
    
    class ReverseHandler(tornado.web.RequestHandler):
    
        def get(self, input):
            self.write(input[::-1] + '
    ')
    
        def head(self):
            self.set_status(200)  # 返回指定状态码
    
    
    class WrapHandler(tornado.web.RequestHandler):
    
        def post(self):
            text = self.get_argument('text')
            width = self.get_argument('width', 40)
            self.write(textwrap.fill(text, int(width)) + '
    ')
    
        def write_error(self, status_code, **kwargs):
            self.write("Gosh darnit, user! You caused a {0} error.
    ".format(
                status_code))
    
    
    if __name__ == "__main__":
        tornado.options.parse_command_line()
        SETTINGS = dict(
            template_path=os.path.join(os.path.dirname(__file__), "templates"),
            static_path=os.path.join(os.path.dirname(__file__), "static"),
        )
        urls = [
            (r"/reverse/(w+)", ReverseHandler),
            (r"/wrap", WrapHandler)
        ]
        app = tornado.web.Application(
            handlers=urls,
            **SETTINGS,
        )
        http_server = tornado.httpserver.HTTPServer(app)
        http_server.listen(options.port)
        tornado.ioloop.IOLoop.instance().start()

    使用自定制SQL操作模块

    # -*- coding: utf-8 -*-
    __author__ = 'CQ'
    
    import pymysql
    import logging
    
    
    logger = logging.getLogger(__name__)
    
    
    class MysqlServer(object):
        """
            Tornado通用连接数据库类
            用pymysql替代tornado使得操作数据库更加灵活,定制化
        """
    
        def __init__(self, db_config):
            try:
                self._db_config = db_config
                self._conn = self.__get_conn()
                self._cursor = self._conn.curson()
            except Exception:
                self.close()
                logger.exception(u"数据库连接失败")
    
        def __get_conn(self):
            connection = pymysql.connect(host=self._db_config['HOST'],
                                         port=self._db_config['PORT'],
                                         user=self._db_config['USERNAME'],
                                         password=self._db_config['PASSWORD'],
                                         db=self._db_config['DB_NAME'],
                                         charset=self._db_config['CHAR_SET'],
                                         )
            connection.ping(True)
            return connection
    
        def ensure_cursor(self):
            if not self._cursor:
                if not self._conn:
                    self._conn = self.__get_conn()
                self._cursor = self._conn.cursor()
    
        def run_sql(self, sql):
            """
                执行完SQL语句需要返回结果
            :param sql:
            :return:
            """
            self.ensure_cursor()
            self._cursor.execute(sql)
            # commit只对innodb生效,不加commit的话,修改数据库记录的操作不会生效。
            # 如果是myisam引擎的话,不需要commit即可生效
            self._conn.commit()
            return self._cursor.fetchall()
    
        def execute_sql(self, sql):
            """
                执行SQL语句无返回值
            :param sql:
            :return:
            """
            self.ensure_cursor()
            self._cursor.execute(sql)
            self._conn.commit()
    
        def run_sql_fetchone(self, sql):
            """
                执行SQL返回一条结果
            :param sql:
            :return:
            """
            self.ensure_cursor()
            self._cursor.execute(sql)
            return self._cursor.fetchone()
    
        def close(self):
            if self._cursor:
                self._cursor.close()
            if self._conn:
                self._conn.close()
            logger.info(u"关闭数据库连接")
    
    
    def test():
        settings = {
            'HOST': "127.0.0.1",
            'PORT': "3306",
            'USERNAME': "root",
            'PASSWORD': "123456",
            'DB_NAME': "test",
            'CHAR_SET': "utf8",
        }
        db = MysqlServer(settings)
        sql = "select distinct `node_name` from tb_node"
        ret = db.run_sql(sql)
        db.close()
        return ret
    
    
    if __name__ == "__main__":
        print(test())

    tornado安全相关

    1. 使用Cookie正确的用户登陆到网站,保证编写的后台管理程序不被非法访问
    
    2. tornado的cookie使用加密签名来验证cookie的值有没有被服务器软件以外的人修改
    
    3. 因为恶意脚本并不知道安全密钥,所以不能再应用不知情的情况下修改cookie,从而达到安全认证的目的

    使用cookie做简单用户验证

    # -*- coding: utf-8 -*-
    __author__ = 'CQ'
    
    import tornado.httpserver
    import tornado.ioloop
    import tornado.options
    import tornado.web
    import tornado.httpclient
    
    import os
    import json
    
    
    from tornado.options import define, options
    define("port", default=8888, help="run on the given port", type=int)
    
    
    class BaseHandler(tornado.web.RequestHandler):
    
        def get_current_user(self):
            return self.get_secure_cookie("username")  # 将用户cookie解密在把值返回
    
    
    class LoginHandler(BaseHandler):
    
        def get(self):
            self.render('login.html')
    
        def post(self):
            self.set_secure_cookie("username", self.get_argument("username"))
            self.redirect("/")
    
    
    class WelcomeHandler(BaseHandler):
        @tornado.web.authenticated  # tornado Web自身提供,没有登录时,自动跳转到登录界面,做身份验证用的
        def get(self):
            self.render("welcome.html", username=self.current_user)
    
    
    class LogoutHandler(BaseHandler):
    
        def get(self):
            self.clear_cookie("username")
            self.redirect("/")
    
    
    if __name__ == "__main__":
        settings = {
            "template_path": os.path.join(os.path.dirname(__file__), "templates"),
            # cookie不会以明文存储在客户端,而是用此字符串加密cookie,然后才存储在客户端
            "cookie_secret": "AQAAALudVkKt/AYA0bLPykwXoIBRVYTO",
            # 当用户没有登录时,tornado会自动跳转的登录URL请求用户登录
            "login_url": "/login"
        }
        urls = [
            (r'/', WelcomeHandler),
            (r'/login', LoginHandler),
            (r'/test', WelcomeHandler),
            (r'/logout', LogoutHandler)
        ]
    
        app = tornado.web.Application(
            handlers=urls,
            **settings,
        )
        http_server = tornado.httpserver.HTTPServer(app)
        http_server.listen(options.port)
        tornado.ioloop.IOLoop.instance().start()

    项目部署方式

    1 fastcgi方式
    2 http方法

     

  • 相关阅读:
    【转】用微软的Live Writer离线写新浪博文
    【转】充满想象力的 Web 调色板
    【转】安装Windows Live Writer后需要做的五件事
    【转】Form Design 设计友善的表单
    【转】从电子政务网络建设迈向政府数据中心建设
    (CF1394 A)Boboniu Chats with Du
    (CF1384B2)Koa and the Beach (Hard Version)
    牛客第十场自闭
    ORACLE 日期加减操作 xiao
    python 占位符
  • 原文地址:https://www.cnblogs.com/cq146637/p/8389944.html
Copyright © 2020-2023  润新知