Files
fastapi-best-architecture/backend/common/socketio/server.py
T
Wu Clan 05bb98dada Update user id context setting location (#1110)
* Update user id context setting location

* Update jwt middleware

* Fix lint
2026-03-19 11:48:11 +08:00

58 lines
1.7 KiB
Python

import urllib.parse
import uuid
import socketio
from starlette_context import request_cycle_context
from backend.common.log import log
from backend.common.security.jwt import jwt_authentication
from backend.core.conf import settings
from backend.database.redis import redis_client
# 创建 Socket.IO 服务器实例
sio = socketio.AsyncServer(
client_manager=socketio.AsyncRedisManager(
f'redis://:{urllib.parse.quote(settings.REDIS_PASSWORD)}@{settings.REDIS_HOST}:{settings.REDIS_PORT}/{settings.REDIS_DATABASE}',
),
async_mode='asgi',
cors_allowed_origins=settings.CORS_ALLOWED_ORIGINS,
cors_credentials=True,
namespaces=['/ws'],
)
@sio.event
async def connect(sid, environ, auth) -> bool:
"""Socket 连接事件"""
if not auth:
log.error('WebSocket 连接失败:无授权')
return False
session_uuid = auth.get('session_uuid')
token = auth.get('token')
if not token or not session_uuid:
log.error('WebSocket 连接失败:授权失败,请检查')
return False
# 免授权直连
if token == settings.WS_NO_AUTH_MARKER:
await redis_client.sadd(settings.TOKEN_ONLINE_REDIS_PREFIX, session_uuid)
return True
try:
with request_cycle_context({settings.TRACE_ID_REQUEST_HEADER_KEY: uuid.uuid4().hex}):
await jwt_authentication(token)
except Exception as e:
log.info(f'WebSocket 连接失败:{e!s}')
return False
await redis_client.sadd(settings.TOKEN_ONLINE_REDIS_PREFIX, session_uuid)
return True
@sio.event
async def disconnect(sid) -> None:
"""Socket 断开连接事件"""
await redis_client.spop(settings.TOKEN_ONLINE_REDIS_PREFIX)