Tornado简单使用

详解 web 框架 tornado Tornado 是一个强大的 Web 框架,特别适合高并发、长连接、实时通信的应用场景。虽然它的异步编程模型可能比其他框架复杂,但它的高性能和灵活性使其在需要处理大量并发请求的项目中有明显的优势。如果你的项目需要处理 WebSocket 或需要高效的异步处理能力,Tornado 是一个非常好的选择。 阅读详情

Tornado简单使用

1 介绍

Tornado 是一个基于Python的Web服务框架和 异步网络库,它最初由 FriendFeed 开发,后来被 Facebook 收购并开源,通过利用非阻塞网络 I/O, Tornado 可以承载成千上万的活动连接,完美的实现了 长连接、WebSockets, 和其他对于每一位用户来说需要长连接的程序.

# 官网地址
https://www.tornadoweb.org/en/stable/

# 多进程文档
https://www.tornadoweb.org/en/stable/httpserver.html#

# 安装Tornado
pip install tornado==6.3.3 -i https://pypi.tuna.tsinghua.edu.cn/simple

# 原生Websocket标准
https://websockets.spec.whatwg.org/

2 简单使用

helloword.py

import asyncio
import tornado

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")

def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
    ])

async def main():
    app = make_app()
    app.listen(8888)
    await asyncio.Event().wait()

if __name__ == "__main__":
    asyncio.run(main())

请求地址

# 地址
http://127.0.0.1:8888/

# 返回值
Hello, world

3 简单Web工程

3.1 Python代码

工程目录

在这里插入图片描述

base_web_handler.py

import logging

import tornado
from tornado.escape import json_decode, to_unicode


class BaseHandler(tornado.web.RequestHandler):

    # def set_default_headers(self):
    # 设置参数
    # pass

    def get_json_argument(self, name, default=None):
        # 解析参数
        args = {}
        try:
            args = json_decode(self.request.body)
        except Exception as e:
            logging.info("json is error")
            pass
        # 编码数据
        name = to_unicode(name)

        # 解析参数
        if name in args:
            return args[name]
        elif default is not None:
            return default
        else:
            # 通知参数异常
            raise tornado.web.MissingArgumentError(name)

message_handler.py

import tornado.websocket


class MessageWebSocket(tornado.websocket.WebSocketHandler):

    # 验证连接
    def check_origin(self, origin):
        # 用于验证跨域(cross-origin requests)
        print(origin)

        # 返回true才能连接,返回false不能连接
        return True

    def open(self):
        # 建立连接
        print("WebSocket opened")

    def on_message(self, message):
        print("Received message:", message)

        self.write_message("Received message:" + "zhonguodoe")
        pass

    def on_close(self):
        print("WebSocket closed")

form_handler.py

from config.base_web_handler import BaseHandler


class FormHandler(BaseHandler):

    def get(self):
        # 获取表单参数
        print(self.get_arguments("name"))
        print(self.get_argument("name"))

        print(self.get_body_arguments("name"))
        print(self.get_body_argument("name"))

        self.write("Hello, world")

json_handler.py



from config.base_web_handler import BaseHandler


class JsonHandler(BaseHandler):
    # post方法
    def post(self):
        # 获取body参数
        # 注意:Tornado本身没有将body解析json的方法,下面方法是自己封装的BaseHandler中构建的
        print(self.get_json_argument("data"))

        self.write("Hello, world")

sse_handler.py

import asyncio

from tornado import gen

from config.base_web_handler import BaseHandler


class SseHandler(BaseHandler):
    def set_default_headers(self):
        # 设置为事件驱动模式
        self.set_header('Content-Type', "text/event-stream")
        # 不使用缓存
        self.set_header('Content-Control', "no-cache")
        # 保持长连接
        self.set_header('Connection', "keep-alive")
        # 允许跨域
        self.set_header('Access-Control-Allow-Origin', "*")

    # 使用协程调度实现并发
    @gen.coroutine
    def get(self):
        # 使用生成器来发送数据流
        for i in range(3):
            self.write(self.build_message("test" + str(i)))
            yield asyncio.sleep(1)
            print("test1" + str(i))

            # 发送数据并在这里暂停,直到下一次生成器被迭代
            self.flush()

        # 数据流发送完毕后,调用finish结束请求
        self.finish()


    def build_message(sekf, message: str, event="message"):
        """
        构建消息
        :param message: 数据消息
        :param event: 事件,默认事件是“message”,可以根据自己的需求定制事件,对应前端的eventSource.addEventListener('message',()=>{}, false)中的message。
        :return:
        """
        head = "event:" + event + "\n" + "data:"
        tail = "\n\n"
        return head + message + tail

main.py

import asyncio

import tornado
from tornado.httpserver import HTTPServer
from tornado.netutil import bind_sockets

from route import make_app


# 单进程
async def main():
    app = make_app()
    app.listen(8881)
    await asyncio.Event().wait()

if __name__ == "__main__":
    asyncio.run(main())



"""

# 多进程,只有在多颗CPU上才能运行,不支持Windows
def main():
    sockets = bind_sockets(8888)
    tornado.process.fork_processes(0)

    async def post_fork_main():
        # 创建APP
        app = make_app()

        # 创建服务
        server = HTTPServer(app)
        server.add_sockets(sockets)
        await asyncio.Event().wait()

    asyncio.run(post_fork_main())


if __name__ == '__main__':
    main()
    
"""

route.py

import tornado

from socket_handler.message_handler import MessageWebSocket
from web_handler.form_handler import FormHandler
from web_handler.json_handler import JsonHandler
from web_handler.sse_handler import SseHandler


def make_app():
    return tornado.web.Application([
        # 验证基础表单
        (r"/form", FormHandler),
        (r"/json", JsonHandler),

        (r"/sse", SseHandler),

        # Websocket请求
        (r"/msg", MessageWebSocket),

    ])

3.2 前端代码

Vue3的SSE代码

<script setup lang="ts">
import { onBeforeUnmount} from 'vue'

defineProps<{ msg: string }>()


// 定义EventSource
let eventSource: any = null


// 建立连接
function createSseConnect(dataId: string) {
  if (window.EventSource) {
    // 创建连接
    eventSource = new EventSource('http://127.0.0.1:8881/sse');

    console.log("test");

    // 接收消息
    eventSource.onmessage = (event: MessageEvent) => {
      console.log(event)
      console.log("onmessage:" + dataId + ": " + event.data)
    };

    // // 也可以使用addEventListener实现自定义事件和默认message事件
    // eventSource.addEventListener('message', (event: MessageEvent)=> {
    //     console.log("message" + dataId + ": " + event.data);
    // }, false);


    // 打开连接
    eventSource.onopen = (event: Event) => {
      console.log("onopen:" + dataId + ": " + event)
    };

    // 连接出错时
    eventSource.onerror = (event: Event) => {
      console.log(event)
      console.log("onerror :" + dataId + ": " + event)
      eventSource.close();
    };

  } else {
    console.log("浏览器不支持SSE")
  }
}

// 组件销毁
onBeforeUnmount(() => {
  // 关闭EventSource
  if(eventSource != null){
    eventSource.close()
  }
})

</script>

<template>
  <h1>{{ msg }}</h1>

  <input type="button" value="发送消息" v-on:click="createSseConnect('1234')" />

</template>

<style scoped>
.read-the-docs {
  color: #888;
}
</style>

Html5的WebSocket

<!DOCTYPE HTML>
<html>

<head>
    <meta charset="utf-8">
    <script type="text/javascript">
        function WebSocketTest() {
            if ("WebSocket" in window) {
                // 构建WebSocket
                var ws = new WebSocket("ws://localhost:8881/msg");

                ws.onopen = function () {
                    // Web Socket 已连接上,使用 send() 方法发送数据
                    ws.send("发送数据");
                    alert("数据发送中...");
                };

                ws.onmessage = function (evt) {
                    var received_msg = evt.data;
                    console.log(received_msg)
                    //   alert("数据已接收...");
                };

                ws.onclose = function () {
                    // 关闭 websocket
                    alert("连接已关闭...");
                };
            }else {
                // 浏览器不支持 WebSocket
                alert("您的浏览器不支持 WebSocket!");
            }
        }
    </script>

</head>

<body>

    <div id="sse">
        <a href="javascript:WebSocketTest()">运行 WebSocket</a>
    </div>

</body>

</html>

3.3 请求地址

# 表单请求
http://127.0.0.1:8888/form

在这里插入图片描述

# json请求
http://127.0.0.1:8888/json

在这里插入图片描述

# WebSocket请求
ws://127.0.0.1:8881/msg

在这里插入图片描述

# SSE请求
http://127.0.0.1:8881/sse

在这里插入图片描述

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

相关推荐

tornado框架的简单使用

最近,正在开始使用tornado框架,tornado:有解决高并发,异步非阻塞,即是服务器又是框架,性能优越,速度快。django呢,开发很高效,第三方库齐全,后台管理全自动化。1.首先:安装tornado在cmd下:pip install tornado2.helloworld#!/usr/bin/env Python #coding:utf-8 import tornado.httpserv...

zzzzzztt的博客 5672

tornado 简易教程

引言 回想Django的部署方式 以Django为代表的python web应用部署时采用wsgi协议与服务器对接(被服务器托管),而这类服务器通常都是基于多线程的,也就是说每一个网络请求服务器都会有一个对应的线程来用web应用(如Django)进行处理。 考虑两类应用场景 用户量大,高并发 如秒杀抢购、双十一某宝购物、春节抢火车票 大量的HTTP持久连接 使用同一个...

360linker 1391

Python中用tornado做简单项目

文章目录tornado简单项目git的使用 tornado简单项目 链接: https://blog.csdn.net/xc_zhou/article/details/80637714 异步阻塞等概念: https://www.cnblogs.com/zhangyafei/p/9606765.html Tornado既是一个web server,也是web framework。而它作为web se...

weixin_45414731的博客 717

3.1.1 Python Tornado网站准备

作为一个程序员一定要会做网站,一定要做过网站,我认为这是程序员的标配了。首先,要有一台自己的服务器(没有服务器自己电脑虚拟机也行)。然后,在这台服务器上做一些必要的配置。接下来,就是安装一个框架,这里用的是Tornado框架。1,开发框架框架的功能类似于基础设施,与具体的软件应用无关,但是提供并实现最为基础的软件架构和体系。软件开发者通常依据特定的框架实现更为复杂的商业运用和业务逻辑。这样的软件应...

心雨先生 835

Python的高性能web框架库Tornado

Tornado 是一个 Python 网络框架。使用示例:pythonCopy上面代码启动了一个简单的Tornado Web应用,监听端口8888。总的来说,Tornado是一个有着现代设计特性的Python Web框架,重视速度和高并发。它使用事件驱动的非阻塞I/O,性能和扩展性都很不错。

zhangzhechun的专栏 530

头歌操作系统2023春季课堂练习2.1:外部中断

本关任务:通过相关知识以及实验回答:版本 1 内核的第 6 次时钟中断发生时,断点和恢复点(指令地址)分别是多少?回答问题:当第一行 0/1 字符全部输出完毕的时候一共发生了几次时钟中断,即第一行完全填满时 jiffies 记录的已发生次数为多少?本关任务:通过实际操作回答在输出第一行 0/1 字符的过程中(如下图所示),共发生了几次时钟中断?2.此时 bochs 虚拟机输出的 0/1 字符串是什么?(只填写数字,不填写空格!根据相关知识进行实际操作,一直输入 c 直到 0/1 将第一行完全填满。

weixin_64821608的博客 8129

Python配置Tornado及简单使用

一、安装Tornado   本文这里直接是在Pycharm上安装的FastApi框架, 在终端上,执行如下命令,安装Tornado: pip install tornado   安装非常快,安装完成后会有Successfully installed字样输出,如下所示: 二、简单使用Tornado   直接上代码,如下所示: # coding = utf-8 from typing import Optional, Awaitable import tornado.web import tornado.

youyicc 1393

雷达截面积建模仿真(RCS)

在目标侧,其形状、材料、尺寸(相对于雷达波长)和相对于雷达观察方向的方向等特征都会影响雷达看到的RCS。严格的数学处理超出了讨论的范围,但入射波和目标之间的相互作用可以定性描述。对于给定的散射方向,可以积分求和物体表面电流的振幅相位,当电流同相时,会出现较大的回波幅度。随着目标方向和雷达视角随时间变化,电流振幅和相位会发生变化,形成看似随机的峰值和零点的散射模式,出现“相长”和“相消”干涉。除了雷达到目标的距离外,雷达截面(RCS)是RRE(雷达距离方程)中唯一与目标相关的参数,因此不在雷达设计者的。

qq_30796447的博客 3138

python tornado简单示例

python tornado简单示例 import tornado.ioloop import tornado.web class MainHandler(tornado.web.RequestHandler): """该函数负责相应定位到该RequestHandler的HTTP GET请求的处理""" def get(self): self.write("He...

王飞的博客 1173

STM32F4驱动ADS1220高精度ADC:从SPI配置到数据校准的完整实战指南

本文详细介绍了如何使用STM32F4微控制器驱动ADS1220高精度ADC,涵盖从SPI接口配置、寄存器设置到数据采集与校准的全过程。通过实战代码示例和硬件设计要点,帮助开发者快速构建高精度数据采集系统,适用于工业测量和精密仪器等应用场景。

weixin_26918763的博客 224

刷题单向链表

实现一个数据结构,维护一张表(最初只有一个元素 11)。接下来 qq 行,每行表示一次操作,操作具体间题目描述。a[i] 里面放的是下一个元素,为0代表链表结束。如单链表1->4 -> 2->3->0用数组表示是。对于每个操作 2,输出一个数字,用换行隔开。第一行一个整数 qq 表示操作次数。

power的专栏 1714

Tornado初学篇(一) 安装Tornado及创建一个简单的项目

一、安装Tornado pip install tornado 二、编写一个简单的Tornado项目 # tornado.web tornado的基础web框架 import tornado.web # tornado 的核心IO循环模块,封装了linux的epoll和BSD的kqueue,是tornado高效的基础 import tornado.ioloop #类似于Django中的...

qq_42142258的博客 1827

Android中的Service:Binder,Messenger,AIDL(2)

前言前面一篇博文介绍了关于Service的一些基本知识,包括service是什么,怎么创建一个service,创建了一个service之后如何启动它等等。在这一篇博文里有一些需要前一篇铺垫的东西,建议没有看过前一篇博文的同学先去看一下前一篇: Android中的Service:默默的奉献者 (1) 。但是在前一篇博文中也有一些遗漏的东西——主要是关于bindService()这一块的具体细节。由于这

lypeer的专栏 5万+

tornado实现简单登录注册

需要前台两个HTML文件来进行跳转,而对于连接两个HTML文件是后台的操作。这时就需要一个.py文件来处理。其中两个HTML文件要写入template文件夹下,而template要和.py文件在同一目录下:我们将其中一个HTML文件命名为index,代码如下:&lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt;&lt;title&gt;Poem M...

Chloe's blog 1795

RuntimeError: The current installed version of g++ (4.8.5) is less than the mininum version CUDA解决方案

本文主要介绍了RuntimeError: The current installed version of g++ (4.8.5) is less than the mininum version CUDA解决方案,希望能对学习python的同学们有所帮助。 文章目录 1. 问题描述 2. 解决方案

weixin_43178406的博客 8万+

YOLOv12改进策略【独家融合改进】| SPD-Conv+PPA 再次提升模型针对小目标的特征提取能力

SPD-Conv是一种新的 CNN 构建模块,用于替代传统 CNN 架构中使用的步长卷积(strided convolution)和池化(pooling)层,它由空间到深度(Space-to-depth,SPD)层和非步长卷积(non - strided convolution)层组成。

Limiiiing的博客 1028

python tornado_python-tornado简单使用

首先附上tornado官方网站tornado(看官网最全)安装tornado:pip installtornado先从hello world开始import tornado.ioloopimport tornado.web#定义处理类型class MainHandler(tornado.web.RequestHandler):#添加一个处理get请求方式的方法def get(self):se...

weixin_39901943的博客 255

华为OD机试 - 报文响应时间 - 贪心算法、位运算(Python/JS/C/C++ 2024 E卷 200分)

贪心算法是在每一步选择中都做出当前最优的选择,期望通过局部最优解推导出全局最优解的算法。

学Java,找哪吒 1758

【Tornado】Tornado简单服务器搭建(简单的例子)

官方网站:http://old.sebug.net/paper/books/tornado/ FriendFeed使用了一款使用 Python 编写的,相对简单的 非阻塞式 Web 服务器。其应用程序使用的 Web 框架看起来有些像web.py或者 Google 的webapp, 不过为了能有效利用非阻塞式服务器环境,这个 Web 框架还包含了一些相关的有用工具 和优化。 Torn...

走在搬砖的路上! 1125

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

tornado框架最简单实现

最简单的tornado服务器 官方入门入口http://demo.pythoner.com/itt2zh/index.html #coding:utf-8 import tornado.web import tornado.ioloop import tornado.options import tornado.httpserver import osfrom tornado.option

Chuweitao_1992130的专栏 1735

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Tornado项目简单搭建

方法一: # 导入相关服务模块 import tornado.httpserver import tornado.ioloop import tornado.web class IndexHandler(tornado.web.RequestHandler): def get(self, *args, **kwargs): self.write("Hello Wo...

zhu6201976的博客 7万+

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

python web框架之Tornado的简单使用

python web框架有很多,比如常用的有django,flask等。今天主要介绍Tornado ,Tornado是一个用Python写的相对简单的、不设障碍的Web服务器架构,用以处理上万的同时的连接口,让实时的Web服务通畅起来。虽然跟现在的一些用Python写的Web架构相似,比如Django,但Tornado更注重速度,能够处理海量的同时发生的流量。接下来,就开始撸...

anyan9579的博客 222

python tornado简单示例之文件上传

python tornado简单示例之文件上传 python tornado简单示例 import tornado.web import tornado.ioloop class UploadHandler(tornado.web.RequestHandler): def get(self, *args, **kwargs): self.render('template...

王飞的博客 551

tornado的简单使用

功能描述实现一个类似与令牌桶的服务,包含一个定时任务,生成令牌,对外提供一个接口用于获取令牌,每获取一次,桶内令牌相应减少实现方案采用redis+tornado的方式实现,代码很简单,不过这里写这个主要是为了说明tornado的简单使用,同时介绍了一个tornado下的高效的redis异步库的使用目录和文件结构Makefile setup.py version.py .bumpversion.cfg

Gary,Done的专栏 1961

tornado 简单的跑通

tornado最简单的跑通 import tornado.web ''' tornado的基础web框架模块 ''' import tornado.ioloop ''' tornado 核心 IO 循环模块 封装了Linux的epoll和BSD的kqueue ''' class IndexHandler(tornado.web.RequestHandler): def get(self,...

dandanfengyun的博客 342

tornado框架简单演示

前端代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>提交</title> <style type="text/css"> .box1{ margin: auto; width: 300px; height: min

北冥有鱼的博客 206
上一篇: Ubuntu22.04安装RTX3080
下一篇: 简单使用vllm
MasonYyp
博客等级 码龄9年 301粉丝 297原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值