WebSocket接收Webhook后无法向前端推送消息,请求排查问题
问题分析与解决方案
核心问题
- WebSocket连接监听时机错误:你在Webhook请求触发后才注册
wss.on("connection")事件,但客户端早在Webhook调用前就已经完成连接了。这个事件只会在新连接建立时触发,此时不会有回调执行,自然无法推送消息。 - 无在线客户端管理机制:当前代码没有保存已连接的WebSocket客户端实例,Webhook触发时找不到已在线的客户端,无法直接推送消息。
修正后的服务端代码
const app = express(); const server = http.createServer(app); const wss = new WebSocket.Server({ server: server }); // 维护已连接的客户端集合 const connectedClients = new Set(); // 客户端连接时加入集合(提前监听,不要放在Webhook里) wss.on("connection", function connection(ws) { console.log("新客户端连接"); connectedClients.add(ws); // 客户端断开连接时从集合移除 ws.on("close", () => { connectedClients.delete(ws); }); // 处理客户端异常,避免内存泄漏 ws.on("error", (error) => { console.error("WebSocket错误:", error); connectedClients.delete(ws); }); }); app.post("/webhook", async (req, res) => { const { status, result_url } = req.body; if (status === "done") { console.log("Webhook called: " + result_url); // 遍历所有在线客户端推送消息 connectedClients.forEach((ws) => { // 检查连接状态,避免向已断开的客户端发送 if (ws.readyState === WebSocket.OPEN) { ws.send("I am from backend post" + result_url); } }); res.json({ output: "消息已推送" }); } else { res.json({ output: "Webhook response" }); } });
修正说明
- 提前监听连接事件:在Webhook路由外部注册
wss.on("connection"),确保客户端连接时能被及时捕获并加入集合。 - 管理在线客户端:用
Set存储所有在线客户端实例,Webhook触发时直接遍历集合推送消息。 - 清理无效连接:监听客户端的
close和error事件,及时从集合中移除断开的客户端,避免无效推送和内存泄漏。 - 校验连接状态:推送前判断客户端连接是否处于
OPEN状态,防止发送失败报错。
内容的提问来源于stack exchange,提问作者Kiran S youtube channel
相关产品推荐
相关产品推荐

