如何解决Next.js停止数据流时的挂起问题?(Vercel AI SDK+OpenAI)
Next.js 14 + Vercel AI SDK:调用useChat的stop()时出现ECONNRESET错误的解决
问题核心
使用Next.js 14(App Router)结合Vercel AI SDK的useChat()实现流式对话,调用stop()终止数据流时,终端抛出ECONNRESET错误,提示「数据流挂起,是否忘记调用data.close()」。
原因分析
当你调用前端的stop()方法时,实际上触发了请求中止(Abort)操作,后端流式响应会被强制中断。但原代码仅在流正常结束时通过onFinal()调用data.close(),请求中止的场景并不会触发该逻辑,导致StreamData实例未被正确关闭,进而引发报错。
你的解决方案是最优方案
你添加的request.signal abort事件监听是正确且推荐的处理方式,它能在请求被中止时及时关闭StreamData,避免数据流挂起。
修改后的完整route.js代码
import { streamText, StreamingTextResponse, StreamData } from "ai"; import { openai } from "@ai-sdk/openai"; export const runtime = "edge"; export async function POST(request) { const { messages } = await request.json(); const data = new StreamData(); try { data.append({ test: "value" }); const result = await streamText({ model: openai("gpt-3.5-turbo"), messages: [ { role: "system", content: "You are a helpful assistant. You answer any question.", }, ...messages, ], }); // 监听请求中止事件,关闭StreamData request.signal.addEventListener("abort", () => { data.close(); }); const stream = result.toAIStream({ onFinal() { data.close(); }, }); return new StreamingTextResponse(stream, {}, data); } catch (error) { // 异常场景也关闭StreamData,避免资源泄漏 data.close(); throw error; } }
补充说明
- 除了请求中止,用
try/catch/finally包裹逻辑,确保在异常抛出时也能关闭StreamData,避免资源泄漏。 - 前端的
stop()调用逻辑是正确的:通过判断isLoading状态触发stop(),完全符合Vercel AI SDK的使用规范,无需修改。
内容的提问来源于stack exchange,提问作者OpuS
相关产品推荐
相关产品推荐

