当前位置: 首页 > news >正文

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 tornadoclass 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 loggingimport tornado
from tornado.escape import json_decode, to_unicodeclass BaseHandler(tornado.web.RequestHandler):# def set_default_headers(self):# 设置参数# passdef 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 defaultelse:# 通知参数异常raise tornado.web.MissingArgumentError(name)

message_handler.py

import tornado.websocketclass MessageWebSocket(tornado.websocket.WebSocketHandler):# 验证连接def check_origin(self, origin):# 用于验证跨域(cross-origin requests)print(origin)# 返回true才能连接,返回false不能连接return Truedef open(self):# 建立连接print("WebSocket opened")def on_message(self, message):print("Received message:", message)self.write_message("Received message:" + "zhonguodoe")passdef on_close(self):print("WebSocket closed")

form_handler.py

from config.base_web_handler import BaseHandlerclass 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 BaseHandlerclass 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 asynciofrom tornado import genfrom config.base_web_handler import BaseHandlerclass 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.coroutinedef 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 asyncioimport tornado
from tornado.httpserver import HTTPServer
from tornado.netutil import bind_socketsfrom 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():# 创建APPapp = 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 tornadofrom 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 SseHandlerdef 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(() => {// 关闭EventSourceif(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) {// 构建WebSocketvar 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 () {// 关闭 websocketalert("连接已关闭...");};}else {// 浏览器不支持 WebSocketalert("您的浏览器不支持 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

在这里插入图片描述


http://www.mrgr.cn/news/54742.html

相关文章:

  • xlnt加载excel报错:xl/workbook.xml:2:2581: error: attribute ‘localSheetId‘ expected
  • 案例分享—国外优秀UI卡片设计作品赏析
  • Java抽象类
  • msvcp140.dll丢失的解决方法吃鸡
  • Git极速入门
  • vue将页面生成图片 vue生成海报
  • JavaScript 新手必知的基本概念
  • 深入了解 Flannel(3):vxlan在flannel中的作用
  • 【Linux系统编程】冯诺依曼体系结构与操作系统
  • 操作系统之内存管理基本概念
  • SpringCloudAlibaba[Nacos]注册配置中心注册与发现服务
  • CGAL专篇-Kernel计算精度
  • 使用模拟器获取app的素材文件
  • 《30 年失联姐妹的短暂相聚与决绝分手》
  • 整合全文检索引擎 Lucene 添加站内搜索子模块
  • Java中的动态代理——介绍与使用示例
  • 数据库必会面试题(含答案)
  • 数据结构与算法——Java实现 41.对称二叉树
  • LeetCode Hot100 - 滑动窗口篇
  • JavaScript 数组的魔法
  • JVM面试题
  • Linux笔记之文件查找和搜索命令which,find,locate,whereis总结
  • 基于x86_64汇编语言简单教程6: 变量,常量,与运算
  • Axure中继器时间筛选
  • 将 centos7 的根分区由非逻辑卷转换成使用逻辑卷
  • halcon的intensity算子到底是Mean灰度均值最大表示清晰度最高,还是Deviation灰度偏差最大表示清晰度最高?