request和websocket
当然,可以为你详细介绍 FastAPI 中的 Request
对象。Request
对象在 FastAPI 中扮演着重要的角色,负责封装来自客户端的 HTTP 请求信息。了解 Request
对象的使用方法和属性,有助于你更高效地处理请求数据、访问请求上下文以及进行各种操作。
1. 什么是 Request
对象
Request
对象是 FastAPI 提供的一个类,用于表示客户端发送到服务器的 HTTP 请求。它基于 Starlette 的 Request
类,提供了丰富的属性和方法来访问请求的各个部分,如路径参数、查询参数、请求体、头信息等。
2. 如何在路由中使用 Request
对象
在 FastAPI 的路由函数中,你可以通过参数注入的方式使用 Request
对象。只需将 Request
作为函数参数,并使用 from fastapi import Request
导入即可。
示例:
from fastapi import FastAPI, Requestapp = FastAPI()@app.get("/items/{item_id}")
async def read_item(request: Request, item_id: int):client_host = request.client.hostreturn {"item_id": item_id, "client_host": client_host}
在这个示例中,Request
对象被注入到 read_item
路由函数中,可以通过它访问请求的详细信息。
3. Request
对象的主要属性
Request
对象包含了大量有用的属性,以下是一些常用的属性:
-
url
: 请求的完整 URL 对象。request.url # 返回一个 `URL` 对象,包含 scheme、host、path、query 等信息
-
method
: 请求的方法,如 GET、POST、PUT 等。request.method # 例如 'GET'
-
headers
: 请求的头信息,类似于字典。user_agent = request.headers.get('user-agent')
-
query_params
: 请求的查询参数,提供类似字典的接口。params = request.query_params # 例如 {'q': 'search', 'page': '2'}
-
path_params
: 路径参数,定义在路由路径中的变量。path_param = request.path_params.get('item_id')
-
cookies
: 请求中的 cookies,类似于字典。session_id = request.cookies.get('session_id')
-
client
: 客户端的连接信息,包括 IP 地址和端口。client_host = request.client.host client_port = request.client.port
-
state
: 一个用于在请求生命周期中存储自定义状态信息的属性。request.state.some_data = "value"
4. Request
对象的主要方法
除了属性,Request
对象还提供了一些方法,用于处理请求体和其他操作:
-
json()
: 异步方法,用于解析请求体中的 JSON 数据。data = await request.json()
-
form()
: 异步方法,用于解析表单数据(application/x-www-form-urlencoded
或multipart/form-data
)。form_data = await request.form()
-
body()
: 异步方法,获取原始的请求体内容。raw_body = await request.body()
-
stream()
: 异步方法,获取一个异步生成器,用于逐步读取请求体数据。async for chunk in request.stream():process(chunk)
5. Request
对象与其他组件的关系
Request
对象常与以下组件一起使用:
-
依赖注入(Dependency Injection): 可以将
Request
对象作为依赖项注入到其他依赖函数中,方便在不同层级访问请求信息。from fastapi import Dependsasync def get_user_agent(request: Request):return request.headers.get('user-agent')@app.get("/user-agent") async def read_user_agent(user_agent: str = Depends(get_user_agent)):return {"user_agent": user_agent}
-
中间件(Middleware): 中间件可以访问和修改
Request
对象,实现全局请求处理逻辑。from fastapi import FastAPI, Request from starlette.middleware.base import BaseHTTPMiddlewareapp = FastAPI()class CustomMiddleware(BaseHTTPMiddleware):async def dispatch(self, request: Request, call_next):# 在请求处理前执行response = await call_next(request)# 在请求处理后执行response.headers["X-Custom-Header"] = "Custom Value"return responseapp.add_middleware(CustomMiddleware)
6. 示例:使用 Request
对象访问请求数据
以下是一个综合示例,展示如何使用 Request
对象访问各种请求数据:
from fastapi import FastAPI, Request, HTTPException
from typing import Optionalapp = FastAPI()@app.post("/submit")
async def submit_form(request: Request):# 获取请求方法method = request.method # 'POST'# 获取请求 URLurl = str(request.url) # 'http://localhost:8000/submit'# 获取请求头user_agent = request.headers.get('user-agent')# 获取查询参数query_params = request.query_params # immutable multi-dict# 获取路径参数(假设路由定义了路径参数)# path_params = request.path_params# 获取 cookiescookies = request.cookies# 解析 JSON 请求体try:data = await request.json()except Exception:data = None# 解析表单数据# form_data = await request.form()return {"method": method,"url": url,"user_agent": user_agent,"query_params": query_params,"cookies": cookies,"data": data,}@app.get("/items/")
async def read_items(request: Request, q: Optional[str] = None):client_host = request.client.hostreturn {"client_host": client_host, "q": q}
在这个示例中:
/submit
路由接收一个 POST 请求,并通过Request
对象访问请求方法、URL、头信息、查询参数、cookies 和请求体数据。/items/
路由接收一个 GET 请求,展示如何获取客户端的 IP 地址和查询参数。
7. 注意事项
-
异步操作:
Request
对象的方法如json()
、form()
和body()
是异步方法,必须使用await
来调用。data = await request.json()
-
多次读取请求体: 由于请求体是一次性可读取的流,避免在同一个请求中多次读取请求体,否则会导致错误或空数据。
-
性能考虑: 对于大型请求体,避免一次性加载所有数据,可以使用
stream()
方法逐步处理。 -
错误处理: 在解析请求体时,捕获可能的异常,如 JSON 解析错误,防止应用崩溃。
8. Request
对象与 WebSocket
对象的区别
虽然 Request
对象和 WebSocket
对象都用于处理客户端的连接请求,但它们在使用场景和功能上有所不同:
- 使用场景:
Request
对象用于传统的 HTTP 请求(如 GET、POST)。WebSocket
对象用于 WebSocket 连接,实现实时的双向通信。
- 功能差异:
Request
对象提供访问请求头、路径参数、查询参数、请求体等功能。WebSocket
对象提供发送和接收消息的方法,如send_text()
、receive_text()
、send_json()
、receive_json()
等。
示例:
from fastapi import FastAPI, Request, WebSocketapp = FastAPI()@app.get("/http-endpoint")
async def http_endpoint(request: Request):data = await request.json()return {"received_data": data}@app.websocket("/ws-endpoint")
async def websocket_endpoint(websocket: WebSocket):await websocket.accept()data = await websocket.receive_text()await websocket.send_text(f"Message text was: {data}")
在这个示例中:
/http-endpoint
使用Request
对象处理 HTTP 请求,解析 JSON 请求体。/ws-endpoint
使用WebSocket
对象处理 WebSocket 连接,接收和发送文本消息。
总结
Request
对象是 FastAPI 中处理 HTTP 请求的核心组件,提供了丰富的属性和方法来访问和操作请求数据。通过合理地使用 Request
对象,你可以高效地获取请求信息、处理请求体数据,并与其他组件如依赖注入、中间件等协同工作。此外,了解 Request
对象与 WebSocket
对象的区别,有助于在不同的通信场景中选择合适的处理方式。
当然!下面,我将系统性地讲解如何在 FastAPI 中使用 Request
和 WebSocket
对象来获取请求消息、处理请求体数据等操作,并通过一个实战案例(一个简单的聊天室应用)来展示如何应用这些知识。所有代码将附带详细的注释,帮助你更好地理解每一部分的功能和实现。
目录
- FastAPI 的
Request
对象- 访问 HTTP 请求数据
- 常用方法
- 示例:在标准路由中使用
Request
- FastAPI 的
WebSocket
对象- 建立 WebSocket 连接
- 发送和接收消息
- 管理连接
- 结合使用
Request
和WebSocket
- 通过 JWT 进行认证
- 在 HTTP 请求和 WebSocket 之间传递上下文
- 实战案例:构建一个简单的聊天室
- 项目结构
- 设置 FastAPI 应用
- 实现 HTTP 路由使用
Request
- 实现 WebSocket 端点
- 处理消息和数据
- 测试应用
- 总结
1. FastAPI 的 Request
对象
Request
对象是 FastAPI 中用于表示客户端发送的 HTTP 请求的核心组件。它基于 Starlette 的 Request
类,提供了丰富的属性和方法来访问请求的各个部分。
访问 HTTP 请求数据
通过将 Request
对象作为路由函数的参数,可以访问到请求的详细信息,如路径参数、查询参数、请求体、头信息等。
常用方法
-
json()
: 异步方法,用于解析请求体中的 JSON 数据。data = await request.json()
-
form()
: 异步方法,用于解析表单数据(application/x-www-form-urlencoded
或multipart/form-data
)。form_data = await request.form()
-
body()
: 异步方法,获取原始的请求体内容。raw_body = await request.body()
-
stream()
: 异步方法,获取一个异步生成器,用于逐步读取请求体数据。async for chunk in request.stream():process(chunk)
示例:在标准路由中使用 Request
以下示例展示了如何在 FastAPI 的 HTTP 路由中使用 Request
对象访问和处理请求数据。
from fastapi import FastAPI, Request, HTTPException
from typing import Optionalapp = FastAPI()@app.post("/submit")
async def submit_form(request: Request):"""处理提交的表单数据。通过 Request 对象访问请求的各种数据,如方法、URL、头信息、查询参数、cookies 和请求体。"""# 获取请求方法,如 'POST'method = request.method# 获取请求的完整 URL,如 'http://localhost:8000/submit'url = str(request.url)# 获取特定的请求头,例如 'User-Agent'user_agent = request.headers.get('user-agent')# 获取所有查询参数,返回一个不可变的多重字典query_params = request.query_params# 获取所有 cookies,返回一个字典cookies = request.cookies# 尝试解析请求体中的 JSON 数据try:data = await request.json()except Exception:# 如果解析失败,设置为 None 或处理异常data = Nonereturn {"method": method,"url": url,"user_agent": user_agent,"query_params": query_params,"cookies": cookies,"data": data,}@app.get("/items/")
async def read_items(request: Request, q: Optional[str] = None):"""读取项目列表,展示如何获取客户端的 IP 地址和查询参数。- `q`: 可选的查询参数,用于过滤项目。"""# 获取客户端的 IP 地址client_host = request.client.hostreturn {"client_host": client_host, "q": q}
2. FastAPI 的 WebSocket
对象
WebSocket
对象用于处理实时的双向通信,允许服务器和客户端之间进行持续的数据交换。与传统的 HTTP 请求不同,WebSocket 提供了一个持久的连接,可以在不重新建立连接的情况下发送和接收消息。
建立 WebSocket 连接
通过定义 WebSocket 路由,可以处理客户端的 WebSocket 连接请求。
from fastapi import FastAPI, WebSocket, WebSocketDisconnectapp = FastAPI()@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):"""处理客户端的 WebSocket 连接。建立连接后,持续接收和发送消息,直到客户端断开连接。"""# 接受 WebSocket 连接请求await websocket.accept()try:while True:# 接收来自客户端的文本消息data = await websocket.receive_text()# 将接收到的消息发送回客户端await websocket.send_text(f"Message text was: {data}")except WebSocketDisconnect:# 处理客户端断开连接的情况print("Client disconnected")
发送和接收消息
-
发送消息:
-
send_text(data: str)
: 发送文本消息。await websocket.send_text("Hello, client!")
-
send_json(data: Any)
: 发送 JSON 格式的消息。await websocket.send_json({"message": "Hello, client!"})
-
send_bytes(data: bytes)
: 发送字节消息。await websocket.send_bytes(b"Hello, client!")
-
-
接收消息:
-
receive_text()
: 接收文本消息。data = await websocket.receive_text()
-
receive_json()
: 接收 JSON 格式的消息。data = await websocket.receive_json()
-
receive_bytes()
: 接收字节消息。data = await websocket.receive_bytes()
-
管理连接
在 WebSocket 应用中,通常需要管理多个连接,包括:
- 跟踪活跃连接:维护一个连接列表或字典,以便向特定客户端发送消息或广播消息。
- 处理连接生命周期:处理连接的建立、消息传递和断开连接的逻辑。
3. 结合使用 Request
和 WebSocket
在实际应用中,可能需要结合使用 Request
和 WebSocket
对象,例如在建立 WebSocket 连接前进行认证,或者在 WebSocket 会话中访问特定的请求上下文信息。
通过 JWT 进行认证
使用 JWT(JSON Web Token)进行认证,可以在建立 WebSocket 连接时验证用户身份。下面是一个示例,展示如何在 WebSocket 连接中使用 JWT 进行认证。
设置认证依赖
首先,配置 JWT 认证相关的依赖。
auth.py
:
from fastapi_jwt_auth import AuthJWT
from pydantic import BaseModelclass Settings(BaseModel):authjwt_secret_key: str = "supersecretkey" # JWT 密钥@AuthJWT.load_config
def get_config():return Settings()
实现 WebSocket 认证
在 WebSocket 路由中,使用 JWT 进行认证。
from fastapi import FastAPI, WebSocket, WebSocketDisconnect, Depends, HTTPException
from fastapi_jwt_auth import AuthJWT
from auth import Settingsapp = FastAPI()@app.websocket("/ws/protected")
async def protected_websocket(websocket: WebSocket, Authorize: AuthJWT = Depends()):"""受保护的 WebSocket 端点,只有通过 JWT 认证的用户可以连接。通过 URL 查询参数传递 JWT 令牌。"""try:# 从查询参数中获取 JWT 令牌token = websocket.query_params.get("token")if not token:# 如果没有提供令牌,关闭连接并返回未授权错误await websocket.close(code=1008, reason="Unauthorized: No token provided")return# 使用 JWT 进行认证Authorize.jwt_required(auth_from="websocket", token=token)# 获取 JWT 中的主题(通常是用户名或用户 ID)user = Authorize.get_jwt_subject()# 接受 WebSocket 连接await websocket.accept()# 发送认证成功消息await websocket.send_text(f"Hello {user}, you are authenticated!")# 持续接收和处理消息while True:data = await websocket.receive_text()# 这里可以添加逻辑处理接收到的消息await websocket.send_text(f"{user} says: {data}")except Exception as e:# 处理认证失败或其他异常,关闭连接await websocket.close(code=1008, reason="Unauthorized")
在 HTTP 请求和 WebSocket 之间传递上下文
可以在 HTTP 请求中生成一些上下文信息,并在 WebSocket 连接中使用这些信息。例如,通过 HTTP 请求创建一个会话 ID,然后在 WebSocket 连接中使用该会话 ID 进行消息传递。
from fastapi import FastAPI, Request, WebSocket, Depends
from fastapi.responses import JSONResponse
from typing import Dict
import uuidapp = FastAPI()# 简单的内存存储,用于管理会话和连接
connections: Dict[str, WebSocket] = {}@app.post("/create-session")
async def create_session():"""创建一个新的聊天会话,并返回唯一的会话 ID。"""# 生成唯一的会话 IDsession_id = str(uuid.uuid4())return {"session_id": session_id}@app.websocket("/ws/{session_id}")
async def websocket_endpoint(websocket: WebSocket, session_id: str):"""WebSocket 端点,使用会话 ID 来管理连接。客户端需要通过 URL 提供会话 ID,以建立与特定会话的连接。"""await websocket.accept()# 将 WebSocket 连接与会话 ID 关联connections[session_id] = websockettry:while True:# 接收消息data = await websocket.receive_text()# 处理消息,例如广播给同一会话的其他客户端# 这里简单地将消息回发给发送者await websocket.send_text(f"Session {session_id}: {data}")except WebSocketDisconnect:# 处理客户端断开连接,移除会话关联del connections[session_id]print(f"Session {session_id} disconnected")
4. 实战案例:构建一个简单的聊天室
通过一个实战案例,整合使用 Request
和 WebSocket
对象,构建一个简单的聊天室应用。这个聊天室允许用户通过 WebSocket 连接发送和接收消息,同时使用 HTTP 请求进行用户认证。
项目结构
chat_app/
├── main.py
├── dependencies.py
├── schemas.py
├── auth.py
└── requirements.txt
1. 设置 FastAPI 应用
首先,创建项目文件并安装所需依赖。
requirements.txt
:
fastapi
uvicorn
fastapi-jwt-auth
pydantic
安装依赖:
pip install -r requirements.txt
2. 定义依赖和认证
创建 auth.py
和 schemas.py
文件,处理用户认证和数据模式。
auth.py
:
# auth.pyfrom fastapi_jwt_auth import AuthJWT
from pydantic import BaseModelclass Settings(BaseModel):authjwt_secret_key: str = "supersecretkey" # 设置 JWT 的密钥authjwt_access_token_expires: int = 60 * 60 # 访问令牌过期时间(秒)@AuthJWT.load_config
def get_config():"""加载 JWT 配置。FastAPI-JWT-Auth 使用这个配置类来获取 JWT 的相关设置。"""return Settings()# 模拟的用户数据库,用于示例认证
fake_users_db = {"user1": {"username": "user1", "password": "password1"},"user2": {"username": "user2", "password": "password2"},
}def authenticate_user(username: str, password: str):"""验证用户凭证。在实际应用中,应从数据库中查询用户并验证密码。"""user = fake_users_db.get(username)if user and user["password"] == password:return userreturn None
schemas.py
:
# schemas.pyfrom pydantic import BaseModelclass UserLogin(BaseModel):"""用户登录的请求数据模式。包含用户名和密码字段。"""username: strpassword: strclass Message(BaseModel):"""聊天消息的数据模式。包含发送者的用户名和消息内容。"""username: strmessage: str
3. 创建主应用和路由
main.py
:
# main.pyfrom fastapi import FastAPI, WebSocket, WebSocketDisconnect, Depends, HTTPException
from fastapi.responses import HTMLResponse
from fastapi_jwt_auth import AuthJWT
from auth import authenticate_user
from schemas import UserLogin, Message
from typing import List
import uuidapp = FastAPI()# 内存中的连接管理类,用于跟踪和管理活跃的 WebSocket 连接
class ConnectionManager:def __init__(self):# 存储所有活跃的 WebSocket 连接self.active_connections: List[WebSocket] = []# 存储 WebSocket 连接对应的用户名self.users = {}async def connect(self, websocket: WebSocket, username: str):"""添加新的 WebSocket 连接到活跃连接列表,并记录用户名。"""await websocket.accept() # 接受连接请求self.active_connections.append(websocket) # 添加到活跃连接列表self.users[websocket] = username # 记录连接对应的用户名def disconnect(self, websocket: WebSocket):"""从活跃连接列表中移除断开的 WebSocket 连接,并删除对应的用户名记录。"""self.active_connections.remove(websocket)del self.users[websocket]async def broadcast(self, message: str):"""向所有活跃的 WebSocket 连接广播消息。"""for connection in self.active_connections:await connection.send_text(message)async def send_personal_message(self, message: str, websocket: WebSocket):"""向特定的 WebSocket 连接发送消息。"""await websocket.send_text(message)# 创建 ConnectionManager 实例
manager = ConnectionManager()@app.post('/login')
def login(user: UserLogin, Authorize: AuthJWT = Depends()):"""用户登录端点。验证用户凭证,并生成 JWT 令牌。- **username**: 用户名- **password**: 密码"""user_db = authenticate_user(user.username, user.password) # 验证用户if not user_db:# 如果认证失败,返回 401 错误raise HTTPException(status_code=401, detail="Bad username or password")# 创建 JWT 访问令牌,主题为用户名access_token = Authorize.create_access_token(subject=user.username)return {"access_token": access_token}@app.websocket("/ws/chat")
async def websocket_chat(websocket: WebSocket, Authorize: AuthJWT = Depends()):"""聊天 WebSocket 端点。通过 JWT 令牌认证用户身份,允许用户发送和接收消息。- **token**: 通过查询参数传递的 JWT 令牌"""try:# 从查询参数中获取 JWT 令牌token = websocket.query_params.get("token")if not token:# 如果没有提供令牌,关闭连接并返回未授权错误await websocket.close(code=1008, reason="Unauthorized: No token provided")return# 使用 JWT 进行认证Authorize.jwt_required(auth_from="websocket", token=token)# 获取 JWT 中的主题(用户名)username = Authorize.get_jwt_subject()# 连接并记录用户名await manager.connect(websocket, username)# 向所有连接广播用户加入消息await manager.broadcast(f"{username} joined the chat!")while True:# 接收来自客户端的消息data = await websocket.receive_text()# 广播消息给所有连接的客户端await manager.broadcast(f"{username}: {data}")except WebSocketDisconnect:# 处理客户端断开连接的情况,移除连接并广播离开消息manager.disconnect(websocket)await manager.broadcast(f"{username} left the chat!")except Exception as e:# 处理其他异常,关闭连接并返回内部错误await websocket.close(code=1011, reason="Internal server error")# 可选的简单 HTML 页面用于测试 WebSocket 聊天功能
@app.get("/")
async def get():"""返回一个简单的 HTML 页面,用于测试 WebSocket 聊天功能。"""return HTMLResponse("""<!DOCTYPE html><html><head><title>Chat</title></head><body><h1>WebSocket Chat</h1><!-- 输入 JWT 令牌 --><input id="token" type="text" placeholder="Enter JWT token" /><button οnclick="connect()">Connect</button><br/><br/><!-- 显示聊天记录的文本区域 --><textarea id="chatLog" cols="100" rows="20" readonly></textarea><br/><!-- 输入消息的文本框 --><input id="messageText" type="text" placeholder="Type a message" /><button οnclick="sendMessage()">Send</button><script>var ws; // WebSocket 连接对象function connect() {var token = document.getElementById("token").value; // 获取输入的令牌// 创建 WebSocket 连接,传递令牌作为查询参数ws = new WebSocket(`ws://localhost:8000/ws/chat?token=${token}`);// 当收到消息时,追加到聊天记录中ws.onmessage = function(event) {var chatLog = document.getElementById("chatLog");chatLog.value += event.data + "\\n";};// 当连接关闭时,显示关闭原因ws.onclose = function(event) {var chatLog = document.getElementById("chatLog");chatLog.value += "Connection closed: " + event.reason + "\\n";};}function sendMessage() {var input = document.getElementById("messageText");ws.send(input.value); // 发送消息input.value = ''; // 清空输入框}</script></body></html>""")
4. 运行和测试应用
启动 FastAPI 应用
使用 Uvicorn 启动 FastAPI 应用。
uvicorn main:app --reload
步骤1:用户登录
首先,用户需要通过 /login
端点获取 JWT 令牌。
请求:
curl -X POST "http://localhost:8000/login" \-H "Content-Type: application/json" \-d '{"username": "user1", "password": "password1"}'
响应:
{"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6..."
}
步骤2:建立 WebSocket 连接
使用获取到的 access_token
建立 WebSocket 连接。
示例连接 URL:
ws://localhost:8000/ws/chat?token=eyJhbGciOiJIUzI1NiIsInR5cCI6...
你可以通过浏览器访问根路径 http://localhost:8000/
,在提供的 HTML 页面中输入 JWT 令牌并连接。
步骤3:发送和接收消息
- 打开浏览器并访问: http://localhost:8000/
- 输入 JWT 令牌: 将从登录步骤获取的
access_token
粘贴到输入框中。 - 点击“Connect”按钮: 建立 WebSocket 连接。
- 发送消息: 在“Type a message”输入框中输入消息并点击“Send”按钮。
- 查看聊天记录: 所有连接的客户端将接收到广播的消息。
步骤4:断开连接
关闭浏览器或刷新页面,WebSocket 连接将断开,其他连接的客户端将收到离开消息。
5. 处理消息和数据
在上述聊天室应用中,WebSocket
对象用于实时通信,而 Request
对象则用于处理 HTTP 请求,如用户登录。
- 处理 WebSocket 消息:
- 接收消息:
data = await websocket.receive_text()
- 发送消息:
await websocket.send_text(message)
- 接收消息:
- 处理 HTTP 请求数据:
- 解析请求体: 通过 Pydantic 模型,如
UserLogin
- 认证用户: 通过
Authorize
依赖注入和 JWT 令牌生成
- 解析请求体: 通过 Pydantic 模型,如
6. 测试应用
通过上述步骤,你可以测试聊天室应用的功能:
- 用户登录: 获取 JWT 令牌。
- 连接 WebSocket: 使用 JWT 令牌建立连接。
- 发送消息: 在客户端发送消息,所有连接的用户都会接收到消息。
- 断开连接: 关闭 WebSocket 连接,其他用户会收到离线通知。
7. 扩展功能
基于这个简单的聊天室,你可以进一步扩展功能:
- 私聊功能: 允许用户发送私密消息。
- 用户列表: 显示当前在线用户。
- 消息持久化: 将消息存储到数据库中,支持聊天历史查询。
- 高级认证: 支持不同权限的用户角色。
- 多房间: 支持多个聊天房间。
5. 总结
通过以上系统性的讲解和实战案例,你应该对如何在 FastAPI 中使用 Request
和 WebSocket
对象有了全面的了解。以下是关键点的回顾:
Request
对象:- 用于处理传统的 HTTP 请求。
- 提供丰富的方法和属性来访问请求数据。
- 适用于需要解析请求体、访问查询参数、头信息等场景。
WebSocket
对象:- 用于实时的双向通信。
- 允许服务器和客户端之间持续发送和接收消息。
- 适用于聊天、实时通知、协作工具等场景。
- 结合使用:
- 在 WebSocket 连接前,通过 HTTP 请求进行用户认证。
- 使用 JWT 令牌在 WebSocket 连接中验证用户身份。
- 管理多个 WebSocket 连接,广播消息或进行一对一通信。
- 实战案例:
- 构建了一个简单的聊天室应用,展示了如何结合使用
Request
和WebSocket
对象。 - 实现了用户登录、WebSocket 连接、消息广播等功能。
- 提供了扩展功能的思路,方便根据需求进一步开发。
- 构建了一个简单的聊天室应用,展示了如何结合使用
最佳实践建议
- 模块化设计: 将不同功能的逻辑分离到不同的模块或类中,保持代码的清晰和可维护性。
- 错误处理: 确保 WebSocket 端点具备全面的错误处理机制,能够优雅地处理各种异常情况,避免资源泄漏。
- 安全性: 确保所有 WebSocket 连接都经过认证和授权,防止未授权的访问。
- 性能优化:
- 使用异步编程模型(如
asyncio
)处理高并发的 WebSocket 连接。 - 合理管理连接池和任务队列,避免阻塞主事件循环。
- 使用异步编程模型(如
- 测试覆盖: 编写充分的单元测试和集成测试,确保新功能的稳定性和可靠性。
- 日志记录: 在关键步骤和异常处记录详细的日志,便于调试和监控。
相关文章:
request和websocket
当然,可以为你详细介绍 FastAPI 中的 Request 对象。Request 对象在 FastAPI 中扮演着重要的角色,负责封装来自客户端的 HTTP 请求信息。了解 Request 对象的使用方法和属性,有助于你更高效地处理请求数据、访问请求上下文以及进行各种操作。…...
前端【9种前端常见的设计模式】
🌟9种前端常见的设计模式 哈喽小伙伴们,这期给大家整理了一些有关9种前端常见的设计模式,覆盖多方面基础知识,建议大家收藏阅读。 文章目录 🌟9种前端常见的设计模式🌟1. 外观模式🌟 2. 代理模…...
IDEA使用HotSwapHelper进行热部署
目录 前言JDK1.8特殊准备DECVM安装插件安装与配置参考文档相关下载 前言 碰到了一个项目,用jrebel启动项目时一直报错,不用jrebel时又没问题,找不到原因,又不想放弃热部署功能 因此思考能否通过其他方式进行热部署,找…...
【Django-xadmin】
时间长不用,会忘的系列 1、Django-xadmin后台字段显示处理 主要是修改每个模块下adminx.py文件 代码解释:第1行控制表单字段显示第2行控制列表字段显示第3行控制搜索条件第4行控制过滤条件第5行支持单个或多个字段信息修改第6行列表分页,每页显示多少行…...
AI 计算基础设施的战略转折点分析
核心技术范式转移 我们正处于计算架构的重大转折点。第一个根本性转变是从传统的 CPU 编程范式,向以 GPU 为核心的神经网络运算模式转移。这不仅仅是硬件架构的改变,更代表了整个软件开发和应用部署方式的革新。第二个转变则是在这个新的基础设施之上&a…...
Java基于SpringBoot+Vue的IT技术交流和分享平台(附源码+lw+部署)
博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…...
二:OpenStack环境准备-controller node
一:工具、环境准备-controller node 二:OpenStack环境准备-controller node 三:安装服务-controller node 四:工具、环境准备-compute node 五:OpenStack环境准备-compute node 六:安装服务-compute node 七…...
解决stable-diffusion-webui时的问题:No module ‘xformers‘. Proceeding without it
p.s 被另一篇文章坑了,装个xformers把我原先的pytorch降智了&%$^# 注意:!!!xformers非强制安装;可优化显存,提高性能和出图速率,对于GPU能力有限的用户很有用;安装过…...
清理Linux/CentOS7根目录的思路
在使用Linux服务器过程中,经常会遇到磁盘空间不足的问题,好多应用默认安装在根目录下,记录一下如何找到问题所在,清理根目录(/) 1. 检查空间使用情况 1.1 查看分区占用: df -h输出࿱…...
人工智能-深度学习-BP算法
BP算法的核心思想是通过计算损失函数对网络参数的梯度,然后使用梯度下降法来更新网络参数,从而最小化损失函数。 误差反向传播算法(BP)的基本步骤: 前向传播:正向计算得到预测值。 计算损失:通过损失函数计算预测值和真实值的差…...
C++小问题
怎么分辨const修饰的是谁 是限定谁不能被改变的? 在C中,const关键字的用途和位置非常关键,它决定了谁不能被修改。const可以修饰变量、指针、引用等不同的对象,并且具体的作用取决于const的修饰位置。理解const的规则能够帮助我们…...
如何让控件始终处于父容器的居中位置(父容器可任意改变大小)
前言: 大家好,我是上位机马工,硕士毕业4年年入40万,目前在一家自动化公司担任软件经理,从事C#上位机软件开发8年以上!我们在C#开发winform程序的时候,有时候需要将一个控件居中显示,…...
Python 调用 Umi-OCR API 批量识别图片/PDF文档数据
目录 一、需求分析 二、方案设计(概要/详细) 三、技术选型 四、OCR 测试 Demo 五、批量文件识别完整代码实现 六、总结 一、需求分析 市场部同事进行采购或给客户报价时,往往基于过往采购合同数据,给出现在采购或报价的金额…...
Java基础访问修饰符全解析
一、Java 访问修饰符概述 Java 中的访问修饰符用于控制类、方法、变量和构造函数的可见性和访问权限,主要有四种:public、protected、default(无修饰符)和 private。 Java 的访问修饰符在编程中起着至关重要的作用,它…...
朗迪锋亮相2024人因工程与智能系统交互国际会议
2024年11月28日至30日,2024人因工程与智能系统交互国际会议在深圳隆重举办。此次大会以推动我国人因工程学科发展为目标,致力于加强国际学术交流,深入探讨人工智能时代的智能系统交互,旨在培育新质生产力,助力经济社会…...
OpenGL学习过程总结
1、矩阵 参考链接 第三课:矩阵变换...
webGL入门教程_06变换矩阵与绕轴旋转总结
变换矩阵与绕轴旋转总结 目录 1. 变换矩阵简介2. 平移矩阵3. 缩放矩阵4. 旋转矩阵 4.1 绕 Z 轴旋转4.2 绕 X 轴旋转4.3 绕 Y 轴旋转 5. 组合变换矩阵6. 结论 1. 变换矩阵简介 在计算机图形学中,变换矩阵用于在三维空间中对物体进行操作,包括ÿ…...
mysql 查询所有的触发器
SELECTTRIGGER_SCHEMA AS Database,TRIGGER_NAME AS Trigger,EVENT_OBJECT_TABLE AS Table,EVENT_MANIPULATION AS Event,ACTION_STATEMENT AS Statement FROMinformation_schema.TRIGGERS;创建触发器遇到报错: You do not have the SUPER privilege and binary lo…...
基于Java Springboot个人财务APP且微信小程序
一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术:Html、Css、Js、Vue、Element-ui 数据库:MySQL 后端技术:Java、Spring Boot、MyBatis 三、运行环境 开发工具:IDEA/eclipse 微信…...
GateWay使用手册
好的,下面是优化后的版本。为了提高可读性和规范性,我对内容进行了结构化、简化了部分代码,同时增加了注释说明,便于理解。 1. 引入依赖 在 pom.xml 中添加以下依赖: <dependencies><!-- Spring Cloud Gate…...
go语言读取yaml配置文件内容
1、config.yaml配置文件内容假设如下 name: "example" version: 1.0 settings:timeout: 30debug: truefeatures:- feature1- feature22、定义结构体 go语言定义结构体匹配yaml内容 package mainimport ("fmt""log""os""gopkg.…...
Proteus8.17下载安装教程
Proteus是一款嵌入式系统仿真开发软件,实现了从原理图设计、单片机编程、系统仿真到PCB设计,真正实现了从概念到产品的完整设计,其处理器模型支持8051、HC11、PIC10/12/16/18/24/30/DsPIC33、AVR、ARM、8086和MSP430等,能够帮助用…...
【AI】Sklearn
长期更新,建议关注、收藏、点赞。 友情链接: AI中的数学_线代微积分概率论最优化 Python numpy_pandas_matplotlib_spicy 建议路线:机器学习->深度学习->强化学习 目录 预处理模型选择分类实例: 二分类比赛 网格搜索实例&…...
图数据库 | 10、图数据库架构设计——高性能图存储架构(上)
老夫在之前的三大篇内容中,介绍了图数据库的三大组件—图计算、图存储以及图查询语言。(都归拢在图数据库原理、架构与应用这个专栏中了,感兴趣的朋友可以在去找阅读。) 接下来,老夫还将继续深化这三大组件࿰…...
el-table 组件二次封装(vue2)
PublicTable.vue <!-- 公共表格组件 --> <template><div class"table-common"><el-table v-loading"loading" :ref"tableid" border style"width: 100%" :data"tableDatas" :row-key"rowKey&quo…...
张量并行和流水线并行在Transformer中的具体部位
目录 张量并行和流水线并行在Transformer中的具体部位 一、张量并行 二、流水线并行 张量并行和流水线并行在Transformer中的具体部位 张量并行和流水线并行是Transformer模型中用于提高训练效率的两种并行策略。它们分别作用于模型的不同部位,以下是对这两种并行的具体说…...
详解Qt pdf 之QPdfSelection 选择文本类
文章目录 QPdfSelection 类详解前言 详细说明公共函数说明1. 构造函数2. text3. boundingRect4. isEmpty5. startPage6. endPage 使用场景示例代码代码说明总结 QPdfSelection 类详解 前言 QPdfSelection 是 Qt PDF 模块中的一个类,用于表示在 PDF 文档中被选中的…...
一款支持80+语言,包括:拉丁文、中文、阿拉伯文、梵文等开源OCR库
大家好,今天给大家分享一个基于PyTorch的OCR库EasyOCR,它允许开发者通过简单的API调用来读取图片中的文本,无需复杂的模型训练过程。 项目介绍 EasyOCR 是一个基于Python的开源项目,它提供了一个简单易用的光学字符识别ÿ…...
matlab 中的 bug
在matlab中绘图,设置 axe 的背景颜色 axes_in3.Color #00235B ;打印的时候 print(figure_handle1,-dpng,-r300,"merge_yt_ey") ;此时保存的图片无法识别背景颜色 原因在于 matlab 中的 InverseHardcopy 将 InvertHardcopy 设置成 off 则可以解决这个问…...
【算法刷题指南】优先级队列
🌈个人主页: 南桥几晴秋 🌈C专栏: 南桥谈C 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据…...
android user版本默认usb模式为充电模式
android插入usb时会切换至默认设置的模式,debug版本为adb,user版本为mtp protected long getChargingFunctions() {// if ADB is enabled, reset functions to ADB// else enable MTP as usual.if (isAdbEnabled()) {return UsbManager.FUNCTION_ADB;} e…...
[极客大挑战 2019]HardSQL--详细解析
信息搜集 登录系统,有两个可能的注入点: 随便输一下看看传参类型: 都是GET型。 SQL注入 传参 usernameadmin’&password123 传参 usernameadmin&password123’ username和password传参,四种闭合方式只有单引号报错&a…...
java基础概念46-数据结构1
一、引入 List集合的三种实现类使用了不同的数据结构! 二、数据结构的定义 三、常见的数据结构 3-1、栈 特点:先进后出,后进先出。 java内存容器: 3-2、队列 特点:先进先出、后进后出。 栈VS队列-小结 3-3、数组 3-…...
数学建模选MATLAB还是Python?
在进行数学建模时,选择合适的编程语言和工具对于建模的效率和效果至关重要。目前,MATLAB和Python是两个常用的数学建模工具,它们各自有优缺点,适用于不同的场景。本文将从多个维度对MATLAB和Python进行比较,帮助大家做…...
【C++】多线程
目录 一 概念 1 多线程 2 多进程与多线程 3 多线程理解 二 创建线程 1 thread 2 join() 和 detach() 3 this_thread 三 std::mutex 1 lock 和 unlock 2 lock_guard 3 unique_lock 四 condition_variable 五 std::atomic 一 概念 1 多线程 在C11之前࿰…...
【计算机网络】实验2:总线型以太网的特性
实验 2:总线型以太网的特性 一、 实验目的 加深对MAC地址,IP地址,ARP协议的理解。 了解总线型以太网的特性(广播,竞争总线,冲突)。 二、 实验环境 • Cisco Packet Tracer 模拟器 三、 实…...
基于Matlab合成孔径雷达(SAR)回波信号建模与多指标质量评估
本研究基于合成孔径雷达(SAR)技术,建立了一个雷达回波信号的模拟模型,并通过多项评价指标对信号质量进行深入评估。首先,研究定义了与SAR系统相关的关键物理参数,如工作频率、平台速度、脉冲宽度、采样率等…...
spring boot3.3.5 logback-spring.xml 配置
新建 resources/logback-spring.xml 控制台输出颜色有点花 可以自己更改 <?xml version"1.0" encoding"UTF-8"?> <!--关闭文件扫描 scanfalse --> <configuration debug"false" scan"false"><springProperty …...
浅谈C#库之DevExpress
一、DevExpress库介绍 DevExpress是一个功能强大、界面美观的UI组件库,广泛应用于桌面应用程序和Web应用程序的开发中。它提供了丰富的控件和工具,帮助开发人员快速构建现代化的用户界面。DevExpress控件库以其功能丰富、应用简便、界面华丽以及方便定制…...
【webApp之h5端实战】项目基础结构搭建及欢迎页面的实现
这是一个实战项目的webapp,主要是使用原生js/css/html来实现我们的业务。预览下面的实战效果,我们将会从0到1实现这个系列的项目。包括大量的原生js知识,css3动画的开发,以及页面的交互实现。 效果预览 项目准备工作 封装的工具类,用于获取原生dom节点,处理原生dom事件的…...
生成树详解(STP、RSTP、MSTP)
目录 1、STP 1.概述 2.基本概念 3.端口角色及其作用 4.报文结构 5.STP的端口状态 6.三种定时器 7.STP选举步骤 8.配置BPDU的比较原则 9.TCN BPDU 10.临时环路的问题 11.传统STP的不足 拓扑变更处理过程 2、RSTP 1.端口角色 2.端口状态 3.P/A(Propo…...
C++趣味编程:基于树莓派Pico的模拟沙漏-倾斜开关与LED的互动实现
沙漏,作为一种古老的计时工具,利用重力让沙子通过狭小通道,形成了计时效果。在现代,我们可以通过电子元件模拟沙漏的工作原理。本项目利用树莓派Pico、倾斜开关和LED,实现了一个电子沙漏。以下是项目的详细技术解析与C++代码实现。 一、项目概述 1. 项目目标 通过倾斜开关…...
Matlab Simulink 电力电子仿真-单相电压型半桥逆变电路分析
目录 一、单相电压型半桥逆变电路仿真模型 1.电路模型 2.电路模型参数 二、仿真分析 三、总结 1.优缺点 2.应用场景 一、单相电压型半桥逆变电路仿真模型 1.电路模型 单相电压型半桥逆变电路是一种常见的逆变电路,主要用于将直流电源转换为交流电源。 &…...
在超表面中琼斯矩阵的使用
琼斯矩阵(Jones Matrix) 是一种线性代数方法,用于描述光的偏振状态和偏振变化,是偏振光学中重要的数学工具。它在 超表面理论设计 中广泛应用,尤其是在设计和调控光与物质相互作用时,例如偏振控制、相位调制…...
threeJs学习 贴图 :地球
效果图: 贴图以后的效果: vue代码: <template><div class"scene_box"><p>创建纹理贴图TextureLoader</p><div class"canvas"></div></div> </template><script s…...
详解Rust多线程编程
文章目录 多线程模型创建和管理线程自定义线程行为线程传递数据线程间通信线程池错误处理与线程Condvar(条件变量)无锁并发高性能并发库 Rust的多线程编程提供了一种安全、高效的方式来进行并发操作。Rust的并发性设计原则之一是确保线程安全,同时避免运行时的开销&…...
Uniapp触底刷新
在你的代码中,使用了 scroll-view 来实现一个可滚动的评论区域,并且通过监听 scrolltolower 事件来触发 handleScrollToLower 函数,以实现“触底更新”或加载更多评论的功能。 关键部分分析: scroll-view 组件: scroll-view 是一…...
【前端】安装hadoop后,前端启动报错,yarn命令
新安装hadoop后,前端启动项目用yarn命令,报错。 报错:系统找不到指定的路径。 No HADOOP_CONF_DIR set. Please specify it either in yarn-env.cmd or in the environment. 解决:删掉hadoop目录下yarn的文件 检查:…...
T620存储安全方案SoC芯片技术手册
系统资源 集成32位国产CPU CK803S;最高工作频率260Mhz CK803S内置16KB I/D Cache,内置32KB DTCM 32KB ROM;256KB SRAM;8KB SRAM(系统专用) 512KB/1MB 片内Flash 安全算法 支持SM4数据加密,加密性…...
Rust循环引用与多线程并发
循环引用与自引用 循环引用的概念 循环引用指的是两个或多个对象之间相互持有对方的引用。在 Rust 中,由于所有权和生命周期的严格约束,直接创建循环引用通常会导致编译失败。例如: // 错误的循环引用示例 struct Node {next: Option<B…...