基于Fastapi的区分聊天房间的聊天转发功能接口示例

基于房间码(eCode)和用户uid,区分不同的聊天房间进行消息转发。
前端将收到的消息根据房间码(eCode)过滤到不同的聊天记录显示页面

后端demo代码如下:

from fastapi import FastAPI, HTTPException, Body, WebSocketDisconnect
from starlette.websockets import WebSocket
active_connections: Dict[str, WebSocket] = {}

# 使用字典管理不同房间的客户端列表
clients_rooms = {}


@app.websocket("/ws/chat")
async def test_endpoint(websocket: WebSocket):
    # 获取参数 /ws/chat?uid=123&eCode=abc
    uid = websocket.query_params.get("uid")
    eCode = websocket.query_params.get("eCode")
    print(uid)
    # 如果参数为空,关闭连接
    if uid is None:
        await websocket.close()
        return
    
    # 接受连接
    await websocket.accept()
    
    # 如果房间不存在,创建新房间
    if eCode not in clients_rooms:
        clients_rooms[eCode] = []
    
    # 将当前客户端加入对应房间
    clients_rooms[eCode].append(websocket)
    print(f"Room {eCode} clients:", clients_rooms[eCode])
    
    # 处理连接
    print("WebSocket connected:", websocket.client)
    
    try:
        # 循环接收消息
        while True:
            # 接收消息
            data = await websocket.receive_text()
            print(data)
            # 解析消息
            data = json.loads(data)
            
            # 转发消息给房间内的其他客户端
            for client in clients_rooms[eCode].copy():
                # 排除自己
                if client != websocket:
                    try:
                        # 转发给除了自己的其他客户端
                        await client.send_text(json.dumps(data))
                    except Exception as e:
                        print(f"Error sending message: {e}")
                        clients_rooms[eCode].remove(client)
    except WebSocketDisconnect:
        print("Client disconnected")
    finally:
        # 移除断开的客户端
        if websocket in clients_rooms[eCode]:
            clients_rooms[eCode].remove(websocket)
        
        # 如果房间为空,删除房间
        if not clients_rooms[eCode]:
            del clients_rooms[eCode]

posted @ 2024-12-13 10:07  莫颀  阅读(62)  评论(0)    收藏  举报