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

FastAPI Web框架教程 第13章 WebSocket

13-1 WebSocket是什么

WebSocket简介

  • WebSocket是一种在单个TCP连接上进行全双工通信的协议。

  • WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。

  • 在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

WebSocket和HTTP的相同点和不同点

  • WebSocket和HTTP都是解决 客户端-服务端 通信的网络协议。

  • HTTP是单向的,客户端先发起请求,服务端收到请求后再处理这个请求返回响应结果;即先有请求再有响应,且是一个请求对应一个响应;请求时建立连接,响应后断开连接。

  • WebSocket是双向的,客户端发起请求经过三次握手连接后,客户端和服务端就会基于这个连接保持通信,都可以主动向对方发消息。任何一端都可以主动断开这个连接。

  • HTTP是无状态的,WebSocket是有状态的。即如果使用WebSocket,那么只要建立了连接,每次通信时,服务端都知道在和谁通信,不需要借助Cookie或seesion或jwt等登录认证方式。

参考:https://www.geeksforgeeks.org/what-is-web-socket-and-how-it-is-different-from-the-http/

WebSocket的应用

  • 实时web应用
  • 游戏
  • 聊天软件等等

13-2 WebSocket聊天室简易版

  • 使用FastAPI演示浏览器和服务端基于WebSocket,建立连接并双向通信。

  • 前端代码无需掌握,只要了解它在干什么事情即可。

  • 示例中,我们使用 HTMLResponse,通过接口的方式把前端代码响应的浏览器上;但其实直接写一个html文件,手动打开也可以的。

  • 后端使用WebSocket,需要使用WebSocket这个对象,常用如下三个 协程函数。

await websocket.accept()				# 建立连接
data = await websocket.receive_text()	 # 收消息
await websocket.send_text()				# 发消息

想要在fastAPI中使用websocket 需要安装标准版的uvicorn

pip3 install uvicorn[standard]

实例:简单版聊天

from fastapi import FastAPI, WebSocket
from fastapi.responses import HTMLResponseapp = FastAPI()html = """
<!DOCTYPE html>
<html><head><title>Chat</title></head><body><h1>WebSocket Chat</h1><form action="" οnsubmit="sendMessage(event)"><input type="text" id="messageText" autocomplete="off"/><button>Send</button></form><ul id='messages'></ul><script>var ws = new WebSocket("ws://localhost:8000/ws");ws.onmessage = function(event) {var messages = document.getElementById('messages')var message = document.createElement('li')var content = document.createTextNode(event.data)message.appendChild(content)messages.appendChild(message)};function sendMessage(event) {var input = document.getElementById("messageText")ws.send(input.value)input.value = ''event.preventDefault()}</script></body>
</html>
"""@app.get("/")
async def get():return HTMLResponse(html)@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):await websocket.accept()while True:data = await websocket.receive_text()await websocket.send_text(f"Message text was: {data}")

13-3 WebSocket多人在线聊天室

  • 实现多人在线聊天室
  • 处理客户端下线通知
  • 使用时间戳做客户端id

示例1:多人在线聊天室

from typing import Listfrom fastapi import FastAPI, WebSocket, WebSocketDisconnect
from fastapi.responses import HTMLResponseapp = FastAPI()html = """
<!DOCTYPE html>
<html><head><title>Chat</title></head><body><h1>WebSocket Chat</h1><h2>Your ID: <span id="ws-id"></span></h2><form action="" οnsubmit="sendMessage(event)"><input type="text" id="messageText" autocomplete="off"/><button>Send</button></form><ul id='messages'></ul><script>var client_id = Date.now()document.querySelector("#ws-id").textContent = client_id;var ws = new WebSocket(`ws://localhost:8000/ws/${client_id}`);ws.onmessage = function(event) {var messages = document.getElementById('messages')var message = document.createElement('li')var content = document.createTextNode(event.data)message.appendChild(content)messages.appendChild(message)};function sendMessage(event) {var input = document.getElementById("messageText")ws.send(input.value)input.value = ''event.preventDefault()}</script></body>
</html>
"""class ConnectionManager:def __init__(self):self.active_connections: List[WebSocket] = []async def connect(self, websocket: WebSocket):await websocket.accept()self.active_connections.append(websocket)def disconnect(self, websocket: WebSocket):self.active_connections.remove(websocket)async def send_personal_message(self, message: str, websocket: WebSocket):await websocket.send_text(message)async def broadcast(self, message: str):for connection in self.active_connections:await connection.send_text(message)manager = ConnectionManager()@app.get("/")
async def get():return HTMLResponse(html)@app.websocket("/ws/{client_id}")
async def websocket_endpoint(websocket: WebSocket, client_id: int):await manager.connect(websocket)	# 接收连接try:while True:data = await websocket.receive_text()		# 接收数据await manager.send_personal_message(f"You wrote: {data}", websocket)	# 自己发的消息自己看到await manager.broadcast(f"Client #{client_id} says: {data}")			# 广播,发给所有在线的客户端except WebSocketDisconnect:manager.disconnect(websocket)	# 断开连接await manager.broadcast(f"Client #{client_id} left the chat")	# 广播

示例2:优化自己发的消息不重复展示

from typing import Listfrom fastapi import FastAPI, WebSocket, WebSocketDisconnect
from fastapi.responses import HTMLResponseapp = FastAPI()html = """
<!DOCTYPE html>
<html><head><title>Chat</title></head><body><h1>WebSocket Chat</h1><h2>Your ID: <span id="ws-id"></span></h2><form action="" οnsubmit="sendMessage(event)"><input type="text" id="messageText" autocomplete="off"/><button>Send</button></form><ul id='messages'></ul><script>var client_id = Date.now()document.querySelector("#ws-id").textContent = client_id;var ws = new WebSocket(`ws://localhost:8000/ws/${client_id}`);ws.onmessage = function(event) {var messages = document.getElementById('messages')var message = document.createElement('li')var content = document.createTextNode(event.data)message.appendChild(content)messages.appendChild(message)};function sendMessage(event) {var input = document.getElementById("messageText")ws.send(input.value)input.value = ''event.preventDefault()}</script></body>
</html>
"""class ConnectionManager:def __init__(self):self.active_connections: List[WebSocket] = []async def connect(self, websocket: WebSocket):await websocket.accept()self.active_connections.append(websocket)	# 收集有所的在线客户端def disconnect(self, websocket: WebSocket):self.active_connections.remove(websocket)	# 当客户端断线时,更新在线客户端列表async def send_personal_message(self, message: str, websocket: WebSocket):await websocket.send_text(message)async def broadcast(self, message: str, websocket: WebSocket):for connection in self.active_connections:if connection == websocket:		# 判断下,如果是自己就不再发送消息continueawait connection.send_text(message)manager = ConnectionManager()@app.get("/")
async def get():return HTMLResponse(html)@app.websocket("/ws/{client_id}")
async def websocket_endpoint(websocket: WebSocket, client_id: int):await manager.connect(websocket)try:while True:data = await websocket.receive_text()await manager.send_personal_message(f"You wrote: {data}", websocket)await manager.broadcast(f"Client #{client_id} says: {data}", websocket)except WebSocketDisconnect:manager.disconnect(websocket)await manager.broadcast(f"Client #{client_id} left the chat", websocket)

相关文章:

FastAPI Web框架教程 第13章 WebSocket

13-1 WebSocket是什么 WebSocket简介&#xff1a; WebSocket是一种在单个TCP连接上进行全双工通信的协议。 WebSocket使得客户端和服务器之间的数据交换变得更加简单&#xff0c;允许服务端主动向客户端推送数据。 在WebSocket API中&#xff0c;浏览器和服务器只需要完成一…...

将 Elasticsearch 向量数据库引入到数据上的 Azure OpenAI 服务(预览)

作者&#xff1a;来自 Elastic Aditya Tripathi Microsoft 和 Elastic 很高兴地宣布&#xff0c;全球下载次数最多的向量数据库 Elasticsearch 是公共预览版中 Azure OpenAI Service On Your Data 官方支持的向量存储和检索增强搜索技术。 这项突破性的功能使你能够利用 GPT-4 …...

SeLinux 常见的宏

在SeLinux框架中&#xff0c;google定义好了一些宏&#xff0c;我们使用这些宏&#xff0c;开发时可以更加方便。大部分的宏是定义在te_macros文件中 type_transition type_transition source_type target_type : class default_type当主体进程域source_type 对target_type 类…...

图解PyTorch中的torch.gather函数和 scatter 函数

前言 torch.gather在目前基于 transformer or query based 的目标检测中&#xff0c;在最后获取目标结果时&#xff0c;经常用到。 这里记录下用法&#xff0c;防止之后又忘了。 介绍 torch.gather 官方文档对torch.gather()的定义非常简洁 定义&#xff1a;从原tensor中获…...

Pytorch实用教程: torch.tensor()的用法

在PyTorch中&#xff0c;torch.tensor()函数是用来创建张量&#xff08;Tensor&#xff09;的一个非常基础和重要的函数。张量是PyTorch中的基本数据结构&#xff0c;用于存储和操作数据&#xff0c;可以看作是一个高维数组。torch.tensor()函数可以从数据创建新的张量&#xf…...

Java设计模式详解:工厂模式

Java设计模式详解&#xff1a;工厂模式 文章目录 Java设计模式详解&#xff1a;工厂模式前言一、工厂模式是个啥&#xff1f;二、工厂模式怎么用&#xff1f;三、工厂模式啥时候用&#xff1f;四、工厂模式的优点总结 前言 今天咱们来聊聊设计模式中的一位重要成员——工厂模式…...

Python爬虫:爬虫常用伪装手段

目录 前言 一、设置User-Agent 二、设置Referer 三、使用代理IP 四、限制请求频率 总结 前言 随着互联网的快速发展&#xff0c;爬虫技术在网络数据采集方面发挥着重要的作用。然而&#xff0c;由于爬虫的使用可能会对被爬取的网站造成一定的压力&#xff0c;因此&#…...

【数据结构】非线性结构---二叉树

1、树 1.1 树的相关概念 节点的度&#xff1a;一个节点含有的子树的个数称为该节点的度&#xff1b; 如上图&#xff1a;A的为6 叶节点或终端节点&#xff1a;度为0的节点称为叶节点&#xff1b; 如上图&#xff1a;B、C、H、I...等节点为叶节点 非终端节点或分支节点&#…...

【战略前沿】与中国达成生产协议后,飞行汽车即将起飞

【原文】Flying cars edge towards takeoff after Chinese production deal 【作者】Thomas Macaulay 斯洛伐克公司KleinVision签署了一项协议&#xff0c;将大规模生产AirCar。 一辆获得航空认证的飞行汽车向商业化又迈出了一大步。 空中汽车的创造者KleinVision今天宣布出售…...

谷粒商城实战(007 压力测试)

Java项目《谷粒商城》架构师级Java项目实战&#xff0c;对标阿里P6-P7&#xff0c;全网最强 总时长 104:45:00 共408P 此文章包含第141p-第p150的内容 简介 安装jmeter 安装jmeter 使用中文 这样写就是200个线程循环100次 一共是2万个请求 介绍线程组 添加请求 可以是htt…...

使用CSS计数器,在目录名称前加上了序号,让目录看起来更加井然有序

目录&#xff08;Text of Contents缩写为TOC&#xff09;&#xff0c;其实就是一篇文章的概要或简述。这好比&#xff0c;去书店买书&#xff0c;先是被这本书的标题所吸引&#xff0c;而后我们才会&#xff0c;翻开这本书目录&#xff0c;看看这本书主要是在讲些什么&#xff…...

SSH常见运维总结

1 -bash: ssh: command not found 解决办法&#xff1a;"yum install &#xff0d;y openssh-server openssh-clinets" 2 ssh登录时提示&#xff1a;Read from socket failed: Connection reset by peer. 原因&#xff1a;/etc/ssh/下没有ssh*key*文件 解决&…...

uni app 扫雷

闲来无聊。做个扫雷玩玩吧&#xff0c;点击打开&#xff0c;长按标记&#xff0c;标记的点击两次或长按取消标记。所有打开结束 <template><view class"page_main"><view class"add_button" style"width: 100vw; margin-bottom: 20r…...

MATLAB绘制堆叠填充图--巧用句柄

MATLAB绘制堆叠填充图–巧用句柄 目录 MATLAB绘制堆叠填充图--巧用句柄1. 主要原理讲解1.1 主要函数1.2 句柄原理 2. 绘图示例2.1 准备数据2.2 绘制堆叠填充图-使用句柄控制图形属性2.3 设置填充颜色和样式2.4 添加标题和标签2.5 绘图效果 3. 结语 堆叠填充图是一种常见的数据可…...

JQuery的定义

jQuery是一个js库&#xff0c;使用jQuery会比js简单一点 jQuery文件是一个自执行函数 jQuery文件是一个自执行函数 $传递的参数不同&#xff0c;效果也不同&#xff1a; 传递的是匿名函数&#xff0c;那$就是一个入口函数&#xff0c;传递的是一个字符串&#xff0c;那$就…...

【操作系统】FCFS、SJF、HRRN、RR、EDF、LLF调度算法及python实现代码

文章目录 一、先来先服务调度算法&#xff08;FCFS&#xff09; 二、短作业优先调度算法&#xff08;SJF&#xff09; 三、高响应比优先调度算法&#xff08;HRRN&#xff09; 四、轮转调度算法&#xff08;RR&#xff09; 五、最早截至时间优先算法&#xff08;EDF&#…...

Image-Adaptive YOLO for Object Detection in Adverse Weather Conditions(IA-YOLO)

1、总体概述 基于深度学习的目标检测在常规条件的数据集可以获得不错的结果&#xff0c;但是在环境、场景、天气、照度、雾霾等自然条件的综合干扰下&#xff0c;深度学习模型的适应程度变低&#xff0c;检测结果也随之下降&#xff0c;因此研究在复杂气象条件下的目标检测方法…...

Mac电脑Jmeter集成到Jenkins,压测多个接口并生成测试报告

Jenkins支持的JDK版本17、21&#xff0c;通过java -version查看当前JDK版本&#xff0c;确认是否匹配 打开网址https://www.jenkins.io/download 点击下载&#xff0c;选择mac版本 commend空格打开终端&#xff0c;输入安装命令brew install jenkins 安装完成后输入brew servi…...

redis-Hash

一&#xff0c;应用场景 Redis hash 是一个string类型的field和value的映射表&#xff0c;hash特别适合用于存储对象。Set就是一种简化的Hash,只变动key,而value使用默认值填充。 可以将一个Hash表作为一个对象进行存储&#xff0c;表中存放对象的信息。 二&#xff0c;命令 H…...

Kubernetes kafka系列 | Strimzi 部署kafka-bridge

Strimzi kafka集群部署直通车 一、kafka bridge 介绍 Kafka Bridge 是 Apache Kafka 生态系统中的一个工具或组件&#xff0c;用于实现 Kafka 与其他系统或协议之间的通信或集成。Kafka 本身是一个分布式事件流平台&#xff0c;广泛用于构建实时数据流水线和流式应用程序。然而…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

oracle与MySQL数据库之间数据同步的技术要点

Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异&#xff0c;它们的数据同步要求既要保持数据的准确性和一致性&#xff0c;又要处理好性能问题。以下是一些主要的技术要点&#xff1a; 数据结构差异 数据类型差异&#xff…...

工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配

AI3D视觉的工业赋能者 迁移科技成立于2017年&#xff0c;作为行业领先的3D工业相机及视觉系统供应商&#xff0c;累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成&#xff0c;通过稳定、易用、高回报的AI3D视觉系统&#xff0c;为汽车、新能源、金属制造等行…...

Android15默认授权浮窗权限

我们经常有那种需求&#xff0c;客户需要定制的apk集成在ROM中&#xff0c;并且默认授予其【显示在其他应用的上层】权限&#xff0c;也就是我们常说的浮窗权限&#xff0c;那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

SpringCloudGateway 自定义局部过滤器

场景&#xff1a; 将所有请求转化为同一路径请求&#xff08;方便穿网配置&#xff09;在请求头内标识原来路径&#xff0c;然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)

本期内容并不是很难&#xff0c;相信大家会学的很愉快&#xff0c;当然对于有后端基础的朋友来说&#xff0c;本期内容更加容易了解&#xff0c;当然没有基础的也别担心&#xff0c;本期内容会详细解释有关内容 本期用到的软件&#xff1a;yakit&#xff08;因为经过之前好多期…...

LabVIEW双光子成像系统技术

双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制&#xff0c;展现出显著的技术优势&#xff1a; 深层组织穿透能力&#xff1a;适用于活体组织深度成像 高分辨率观测性能&#xff1a;满足微观结构的精细研究需求 低光毒性特点&#xff1a;减少对样本的损伤…...

Caliper 配置文件解析:fisco-bcos.json

config.yaml 文件 config.yaml 是 Caliper 的主配置文件,通常包含以下内容: test:name: fisco-bcos-test # 测试名称description: Performance test of FISCO-BCOS # 测试描述workers:type: local # 工作进程类型number: 5 # 工作进程数量monitor:type: - docker- pro…...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障

关键领域软件测试的"安全密码"&#xff1a;Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力&#xff0c;从金融交易到交通管控&#xff0c;这些关乎国计民生的关键领域…...