扫描二维码

关注或者微信搜一搜:编程智域 前端至全栈交流与成长

发现1000+提升效率与开发的AI工具和实用程序https://tools.cmdragon.cn/

# 示例代码运行环境
# Python 3.8+
# 安装依赖:pip install fastapi==0.68.0 uvicorn==0.15.0 websockets==10.3 pydantic==1.10.7

一、WebSocket路由声明规范

1.1 基础路由定义

使用@app.websocket装饰器声明WebSocket路由:

from fastapi import FastAPI, WebSocket

app = FastAPI()

@app.websocket("/ws/chat/{room_id}")
async def websocket_chat(websocket: WebSocket, room_id: int):
await websocket.accept()
try:
while True:
data = await websocket.receive_text()
await websocket.send_text(f"Room {room_id}: {data}")
except WebSocketDisconnect:
print("Client disconnected")

关键要点解析:

  • 路径参数通过URL直接传递(如{room_id})
  • WebSocket对象自动注入到路由函数
  • 必须显式调用await websocket.accept()建立连接
  • receive_text()和send_text()实现双向通信

1.2 路由参数验证

结合路径参数与查询参数进行复合验证:

from fastapi import Query, WebSocket

@app.websocket("/ws/secure/{client_id}")
async def secure_ws(
websocket: WebSocket,
client_id: int = Path(..., gt=0),
token: str = Query(..., min_length=8)
):
if not validate_token(token):
await websocket.close(code=1008)
return
# ...连接处理逻辑...

二、客户端连接建立与握手验证

2.1 握手过程控制

自定义握手验证流程:

@app.websocket("/ws/auth")
async def auth_ws(websocket: WebSocket):
# 手动控制握手过程
await websocket.accept() # 获取握手时的请求头
headers = websocket.headers
auth_token = headers.get("authorization") if not verify_jwt_token(auth_token):
await websocket.close(code=1008, reason="Invalid credentials")
return # 验证通过后的处理逻辑

2.2 验证失败处理模式

graph TD
A[客户端请求连接] --> B{验证Headers}
B -- 成功 --> C[返回101状态码]
B -- 失败 --> D[返回403状态码]
C --> E[建立双向通信]
D --> F[关闭TCP连接]

三、连接状态维护与生命周期管理

3.1 连接状态跟踪

使用字典维护活跃连接:

from typing import Dict

active_connections: Dict[str, WebSocket] = {}

@app.websocket("/ws/status")
async def status_ws(websocket: WebSocket):
await websocket.accept()
client_id = str(websocket.client)
active_connections[client_id] = websocket try:
while True:
# 保持连接活跃
await websocket.receive_text()
except WebSocketDisconnect:
del active_connections[client_id]

3.2 心跳检测机制

import asyncio

async def heartbeat(websocket: WebSocket, interval: int = 30):
try:
while True:
await asyncio.sleep(interval)
await websocket.send_json({
"type": "heartbeat",
"timestamp": time.time()
})
except WebSocketDisconnect:
print("Heartbeat terminated") @app.websocket("/ws/realtime")
async def realtime_ws(websocket: WebSocket):
await websocket.accept()
# 启动独立心跳任务
heartbeat_task = asyncio.create_task(heartbeat(websocket)) try:
# 主消息处理循环
while True:
data = await websocket.receive_json()
# 处理业务逻辑...
finally:
heartbeat_task.cancel()
await websocket.close()

课后 Quiz

  1. 当客户端发送非文本格式数据时如何处理?
# 正确处理方法
try:
data = await websocket.receive_json()
except WebSocketDisconnect:
# 处理断开逻辑
except ValueError:
await websocket.send_text("ERROR: 仅支持JSON格式") # 错误处理方法:直接使用未校验的receive()
  1. 如何获取客户端的真实IP地址?
# 正确方法
client_ip = websocket.client.host # 常见错误:直接读取X-Forwarded-For头
# 需要配合代理设置处理

常见报错解决方案

错误1:403 Handshake Failed

现象:客户端连接时立即断开

分析:未通过握手验证,常见于:

  • 缺少必要认证头
  • 验证逻辑返回False后未及时close()

    解决
# 在拒绝连接时立即关闭
if not valid:
await websocket.close(code=1008)
return # 必须立即返回

错误2:1006 Abnormal Closure

现象:客户端非正常断开

处理方案

try:
while True:
data = await websocket.receive_text()
except WebSocketDisconnect as e:
print(f"断开代码:{e.code}")

错误3:TypeError: 'str' expected

场景:发送非文本数据时

正确做法

# 发送二进制数据
await websocket.send_bytes(binary_data) # 发送文本数据
await websocket.send_text("message") # 发送JSON
await websocket.send_json({"key": "value"})

余下文章内容请点击跳转至 个人博客页面 或者 扫码关注或者微信搜一搜:编程智域 前端至全栈交流与成长

,阅读完整的文章:如何在FastAPI中玩转WebSocket,让实时通信不再烦恼?

往期文章归档:

免费好用的热门在线工具

FastAPI WebSocket:你的双向通信通道为何如此丝滑?的更多相关文章

  1. happyChat开发系列:使用websocket.io实现双向通信的乐聊大前端开发

    一.前言 乐聊是一个自己用websocket写一个完整的应用,虽然功能比较欠缺,但是实现了基本的文字聊天,以及群聊,私聊,机器人聊天等功能.因为这个自己做了PC端,无线端(手机端),以及使用cordo ...

  2. FastAPI(56)- 使用 Websocket 打造一个迷你聊天室

    背景 在实际项目中,可能会通过前端框架使用 WebSocket 和后端进行通信 这里就来详细讲解下 FastAPI 是如何操作 WebSocket 的 模拟 WebSocket 客户端 #!usr/b ...

  3. WebSocket 浅析

    版权声明:本文由史燕飞原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/241 来源:腾云阁 https://www.qclo ...

  4. 【腾讯Bugly干货分享】WebSocket 浅析

    本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:http://mp.weixin.qq.com/s/7aXMdnajINt0C5dcJy2USg 前言 在W ...

  5. websocket的子协议stomp协议

    stomp协议Spring实现 服务器注册EndPoint 用来与客户端建立websocket连接 websocket连接的建立应该与客户端与服务器之间的通道无关 jdk中 javax下的websoc ...

  6. websocket基本概念

    (1)websocket 协议 与 http协议 websocket 协议,双工通道 socket连接不断开 http 协议 ,只能请求响应 (用户主动获取) socket连接断开 都是基于socke ...

  7. Spring Chapter4 WebSocket 胡乱翻译 (二)

    书接上文,Spring Chapter4 WebSocket 胡乱翻译 (一) 4.4.4. 消息流 一旦暴露了STOMP端点,Spring应用程序就成为连接客户端的STOMP代理. 本节介绍服务器端 ...

  8. HTML5(十二)——一文读懂 WebSocket 原理

    一.WebSocket 由来 WebSocket 是一个持久化的协议,通过第一次 HTTP Request 建立连接之后,再把通信协议升级成 websocket,保持连接状态,后续的数据交换不需要再重 ...

  9. JAVA使用netty建立websocket连接

    依赖 <!-- https://mvnrepository.com/artifact/commons-io/commons-io --> <dependency> <gr ...

  10. FastAPI快速查阅

    官方文档主要侧重点是循序渐进地学习FastAPI, 不利于有其他框架使用经验的人快速查阅 故本文与官方文档不一样, 并补充了一些官方文档没有的内容 安装 包括安装uvicorn $pip instal ...

随机推荐

  1. 二叉树 (王道数据结构 C语言版)

    2004.11.04 计算一颗给定二叉树的所有双分支节点个数 编写把一个树的所有左右子树进行交换的函数 求先序遍历中第k个结点的值 (1 <= k <= 二叉树中的结点个数) #inclu ...

  2. 短信接口被刷爆:我用Nginx临时止血

    最近,朋友公司遇到了一件让他们"寝食难安"的事:他们的短信验证码接口被人盯上了,充进去的钱没多久就被刷得一分不剩.不充钱,业务直接受影响:但充钱吧,就像往无底洞里灌水.他们联系短信 ...

  3. python之request请求后响应的数据从中获取指定值

    request请求后响应的数据为字典类型,从中获取指定值 如上图,需要获取Code的值,或者Msg的值 首先把response通过内置json解码器解码输出 response =  response. ...

  4. 加减法计算在RB中的应用(比如计算库存)(should be equal as integers指令的使用)

    订单测试过程中,对库存的校验是很关键的步骤 下面这个案例即实现对订单前后库存检查.公式计算.结果匹配,输出测试结果.具体脚本如下图 步骤如下: 1.获取订单前的库存 2.订单流程 3.获取订单后的库存 ...

  5. eolinker环境变量配置:用例执行前给把某参数设置为全局参数的方法

    特别注意:需要使用全局变量或者预处理前务必阅读本链接https://www.cnblogs.com/becks/p/13713278.html 1.场景分析 注册会员流程共计有添加数据,校验数据,提交 ...

  6. 自定义控件,重写 TextBox 实例

    项目中可能会遇到重写控件的情况,特此记录下: 1 <Window x:Class="WpfApp6.MainWindow" 2 xmlns="http://sche ...

  7. Python实验3 函数与代码复用

    目的:理解函数封装与递归思想 实验任务: 基础 :编写函数cal_factorial(n)计算阶乘(循环实现). 源码: def cal_factorial(n): result = 1 for i ...

  8. 访问项目resource/static目录下的模板文件(解决Docker部署后访问不到的问题)

    使用ClassPathResource方式获取static下的文件(别的方式本地可以访问到,Docker部署后不行) final String templatePath = "/static ...

  9. 【记录】Google|下载 Google 谷歌商店中的应用的多种方式

    之前我为了下载猫能玩的平板游戏,又不想下载病毒,就找了很多谷歌商店直接下 APK 的方法,以供大家参考. 对猫游戏感兴趣可参考这篇:[记录]Android|安卓平板 猫游戏(四款,peppy cat, ...

  10. 装在U盘或移动固态硬盘里的系统——适用于Ventoy和VirtualBox的Win to go 和 Linux to go 系统制作教程

    写在前面 前段时间, 突然想起了大学期间折腾过的双系统, 又恰逢最近学习工作需要用到Linux系统环境, 用虚拟机又感觉性能跟不上, 因此萌生了一个用移动固态硬盘安装双系统的想法. 照着网络上各位老师 ...