NextJS实现SSE功能时出现API resolved without sending a response告警如何解决
告警触发原因
这个告警是NextJS API路由的默认检查机制导致的,和SSE长连接的需求没有冲突,核心问题有两个:
- RxJS的
subscribe方法返回的是Subscription对象,不是Promise,你用await去等待它没有任何效果,会导致async类型的handler函数立即执行完成,此时你还没有调用res.end(),NextJS默认认为你漏发了响应,就抛出了这个告警。 - 没有显式告诉NextJS这个API路由由你自行控制响应生命周期,它会按照常规短连接接口的规则做校验。
具体修复方案
第一步:添加API路由配置
在你的API文件底部添加如下配置,禁用NextJS的默认响应校验:
export const config = { api: { // 标记该路由为外部解析器控制响应,关闭未返回响应的检查 externalResolver: true, // 如果你的接口不需要接收请求体,可以额外关闭bodyParser减少开销 // bodyParser: false } }
第二步:修正handler的异步逻辑
调整代码,添加客户端断开的监听避免内存泄漏,同时让async handler保持pending状态适配长连接需求:
const handler = async (req: NextApiRequest, res: NextApiResponse) => { // 原有头部设置 res.setHeader("Content-Type", "text/event-stream;charset=utf-8"); res.setHeader("Cache-Control", "no-cache, no-transform"); res.setHeader("Connection", "keep-alive"); // 额外添加该头部,避免NextJS自动压缩破坏SSE的数据格式 res.setHeader("Content-Encoding", "none"); const observer: Observer<RepoInformation> = { next: value => { res.write(`event: received\n`); res.write(`data: ${JSON.stringify(value)}\n\n`); // Node环境下可选调用刷新缓冲区,避免数据积压 res.flush?.(); }, error: (err: Error) => { res.write(`event: data-error\n`); res.write(`data: ${err.message}\n\n`); res.end(); }, complete: () => { res.end(); }, }; const subscription = access$.pipe(mergeMap(svc.repo.listRepos$)) .subscribe(observer); // 监听客户端主动断开连接,清理资源 req.on('close', () => { subscription.unsubscribe(); res.end(); }); // 保持handler pending状态,避免NextJS判定为执行完成 await new Promise(() => {}); }; export default withApiAuthRequired(handler);
修改完成后重启服务,告警就会消失,SSE的长连接功能不受任何影响。
内容的提问来源于stack exchange,提问作者softshipper
相关产品推荐
相关产品推荐

