扫描二维码

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

发现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. 阿里云平台OSS对象存储

    OSS即"OpenStorageService",概念上没啥新意,就是本地存储搬到阿里云平台上了,单个存储对象大小可以达到5G,看了下阿里的OSS教程java版本, 使用原生js和 ...

  2. android点滴-1

    一.关于TSpeedButtons 1.对于TspeedButtons,需要选择适当的StyleLookUp值后,才能在ObjectInspector中出现TintColor属性,根据自己需要进行修改 ...

  3. 记一次 .NET某云HIS系统 CPU爆高分析

    一:背景 1. 讲故事 年前有位朋友找到我,说他们的系统会偶发性的CPU爆高,有时候是爆高几十秒,有时候高达一分多钟,自己有一点分析基础,但还是没找到原因,让我帮忙看下怎么回事? 二:CPU爆高分析 ...

  4. mybatis底层源码

    一.运行原理 二.配置文件的解析以及创建SqlSessionFactory 首先通过配置文件的文件流创建SqlSessionFactoryBuilder对象 调用build方法,传入文件流 之后通过解 ...

  5. ArrayBlockingQueue的take()底层原理

    一.ArrayBlockingQueue 的 take() 方法的底层源码的详细介绍 ArrayBlockingQueue 是 Java 并发包 (java.util.concurrent) 中的一个 ...

  6. IDEA插件-Translation

    简介 Translation是一个为IntelliJ IDEA和其他基于JetBrains的IDE(如 PyCharm.WebStorm 等)设计的插件.这个插件的主要功能是帮助开发者在编写代码或文档 ...

  7. Web前端入门第 35 问:CSS 细说 flex 弹性盒子布局(多图)

    flex 作为现代布局方案中最常用的手段,有必要拉出来细说. flex 相关的 CSS 属性 容器(父元素)相关的 CSS 属性 以下的 CSS 属性,在 flex 布局中需喂给父元素,设置 flex ...

  8. Spring Security认证与授权

    什么是Spring Security Spring Security是基于Spring框架,提供了一套Web应用安全性框架.专门为Java应用提供用户认证(Authentication)和用户授权(A ...

  9. 技术-Todo

    本文描述下一步调研的技术系统 技术 地址 状态 数据库中间件 https://vitess.io/zh/ Todo

  10. 【docker】4种网络模式

    bridge模式 使用--net=bridge指定,Docker的默认设置,这种模式创建出来的docker容器链接到Dcoker网桥上(docker0网桥或者其它自定义的网桥): 1)创建一对虚拟网卡 ...