update:优化了websocket对数据库连接的获取与释放

This commit is contained in:
killua committed 2024-06-20 10:34:26 +08:00
1 parent ce46c0f35b
commit 5a47440e0f
8 files changed
+91 -54

No files matched your search

+43 -21
View File
@@ -2,20 +2,29 @@ from fastapi import FastAPI, Depends, WebSocket, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from config import Config
from app.concrete import Agent
from app.model import Assistant, User, get_db
from app.model import Assistant, User, get_db, get_db_context
from app.schemas import *
from app.dependency import get_logger
from app.exception import *
import asyncio
import uvicorn
import uuid
import json
import time
# 公共函数 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------
def update_messages(messages, kid_text,llm_text):
messages = json.loads(messages)
def update_messages(assistant, kid_text, llm_text):
messages = json.loads(assistant.messages)
if not kid_text:
raise AsrResultNoneError()
if not llm_text:
raise LlmResultNoneError()
messages.append({"role":"user","content":kid_text})
messages.append({"role":"assistant","content":llm_text})
return json.dumps(messages,ensure_ascii=False)
with get_db_context() as db:
db.query(Assistant).filter(Assistant.id == assistant.id).update({"messages":json.dumps(messages,ensure_ascii=False),"token":assistant.token})
db.commit()
# --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
# 引入logger对象
@@ -177,7 +186,7 @@ async def update_user(id: str,request: update_user_request,db=Depends(get_db)):
# 流式聊天websokct接口 ------------------------------------------------------------------------------------------------------------------------------------------------------------
@app.websocket("/api/chat/streaming/temporary")
async def streaming_chat(ws: WebSocket,db=Depends(get_db)):
async def streaming_chat(ws: WebSocket):
await ws.accept()
logger.debug("WebSocket连接成功")
try:
@@ -187,57 +196,70 @@ async def streaming_chat(ws: WebSocket,db=Depends(get_db)):
llm_text = ""
logger.debug("开始进行ASR识别")
while len(asr_results)==0:
chunk = json.loads(await ws.receive_text())
chunk = json.loads(await asyncio.wait_for(ws.receive_text(),timeout=2))
if assistant is None:
assistant = db.query(Assistant).filter(Assistant.id == chunk['meta_info']['session_id']).first()
with get_db_context() as db: #使用with语句获取数据库连接,自动关闭数据库连接
assistant = db.query(Assistant).filter(Assistant.id == chunk['meta_info']['session_id']).first()
if assistant is None:
raise SessionNotFoundError()
user_info = json.loads(assistant.user_info)
if not agent:
agent = Agent(asr_type=user_info['asr_type'], llm_type=user_info['llm_type'], tts_type=user_info['tts_type'])
agent.init_recorder(assistant.user_id)
chunk["audio"] = agent.user_audio_process(chunk["audio"], db)
asr_results = await agent.stream_recognize(chunk, db)
chunk["audio"] = agent.user_audio_process(chunk["audio"])
asr_results = await agent.stream_recognize(chunk)
kid_text = asr_results[0]['text'] #asr结果的[0]默认为孩子(主要用户)的asr结果
logger.debug(f"ASR识别成功,识别结果为:{kid_text}")
prompt = agent.prompt_process(asr_results, db)
prompt = agent.prompt_process(asr_results)
agent.recorder.input_text = prompt
logger.debug("开始调用大模型")
llm_frames = await agent.chat(assistant, prompt, db)
llm_frames = await agent.chat(assistant, prompt)
async for llm_frame in llm_frames:
resp_msgs = agent.llm_msg_process(llm_frame, db)
resp_msgs = agent.llm_msg_process(llm_frame)
for resp_msg in resp_msgs:
llm_text += resp_msg
tts_audio = agent.synthetize(assistant, resp_msg, db)
agent.tts_audio_process(tts_audio, db)
tts_start_time = time.time()
tts_audio = agent.synthetize(assistant, resp_msg)
tts_end_time = time.time()
logger.debug(f"TTS生成音频耗时:{tts_end_time-tts_start_time}s")
agent.tts_audio_process(tts_audio)
await ws.send_bytes(agent.encode(resp_msg, tts_audio))
logger.debug(f'websocket返回:{resp_msg}')
logger.debug(f"大模型返回结束,返回结果为:{llm_text}")
await ws.send_text(json.dumps({"type": "close", "code": 200, "msg": ""}, ensure_ascii=False))
logger.debug("结束帧发送完毕")
assistant.messages = update_messages(assistant.messages, kid_text ,llm_text)
db.commit()
update_messages(assistant, kid_text ,llm_text)
logger.debug("聊天更新成功")
agent.recorder.output_text = llm_text
agent.save()
logger.debug("音频保存成功")
except EnterSlienceMode:
tts_audio = agent.synthetize(assistant, "已进入沉默模式", db)
tts_audio = agent.synthetize(assistant, "已进入沉默模式")
await ws.send_bytes(agent.encode("已进入沉默模式", tts_audio))
await ws.send_text(json.dumps({"type":"info","code":201,"msg":"进入沉默模式"}, ensure_ascii=False))
except SlienceMode:
await ws.send_text(json.dumps({"type":"info","code":201,"msg":"处于沉默模式"}, ensure_ascii=False))
logger.debug("进入沉默模式")
except AsrResultNoneError:
await ws.send_text(json.dumps({"type":"error","code":501,"msg":"asr结果为空"}, ensure_ascii=False))
logger.error("ASR结果为空")
except AbnormalLLMFrame as e:
await ws.send_text(json.dumps({"type":"error","code":502,"msg":str(e)}, ensure_ascii=False))
logger.error(f"LLM模型返回异常,错误信息:{str(e)}")
except SideNoiseError as e:
await ws.send_text(json.dumps({"type":"error","code":503,"msg":str(e)}, ensure_ascii=False))
await ws.send_text(json.dumps({"type":"error","code":503,"msg":"检测为噪声"}, ensure_ascii=False))
logger.debug("检测为噪声")
except SessionNotFoundError:
await ws.send_text(json.dumps({"type":"error","code":504,"msg":"session不存在"}, ensure_ascii=False))
logger.error("session不存在")
except UnknownVolcEngineModelError:
await ws.send_text(json.dumps({"type":"error","code":505,"msg":"未知的火山引擎模型"}, ensure_ascii=False))
logger.error("未知的火山引擎模型")
except LlmResultNoneError:
await ws.send_text(json.dumps({"type":"error","code":506,"msg":"llm结果返回为空"}, ensure_ascii=False))
logger.error("LLM结果返回为空")
except asyncio.TimeoutError:
await ws.send_text(json.dumps({"type":"error","code":507,"msg":"接收超时"}, ensure_ascii=False))
logger.error("接收超时")
logger.debug("WebSocket连接断开")
logger.debug("")
await ws.close()
# --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------