ExpressJS+MQTT接口重复请求触发ERR_HTTP_HEADERS_SENT报错求助
解决ExpressJS API中ERR_HTTP_HEADERS_SENT错误及MQTT消息重复监听问题
问题根源
你的代码在每次PUT /command请求时,都会给MQTT客户端新增一个message事件监听器。首次请求时能正常工作,但后续请求会累积多个监听器——当MQTT服务器返回消息时,所有累积的监听器都会触发,每个都尝试调用res.send(),导致重复发送HTTP响应头,最终抛出ERR_HTTP_HEADERS_SENT错误。此外,订阅hwid后未取消订阅,会导致客户端持续接收该主题的无关消息,进一步干扰后续请求。
修改后的代码
const express = require("express"); const bodyParser = require("body-parser"); const app = express(); const mqtt = require("mqtt"); const client = mqtt.connect("serverip"); client.on("connect", function () { console.log("[API]: Successfully connected to the server"); }); app.use(bodyParser.json()); app.put("/command", (req, res) => { const { hwid, command } = req.body; console.log(`PUT method request for: ${hwid}`); // 定义命名的消息处理回调,方便后续移除 function handleMessage(topic, message) { const messageStr = message.toString(); // 过滤自身发送的命令消息 if (messageStr === command) return; // 仅处理当前请求对应hwid的响应 if (topic !== hwid) return; // 返回响应给客户端 res.send({ hwid: topic, content: messageStr }); // 移除当前请求的消息监听器,避免累积 client.off("message", handleMessage); // 取消订阅该hwid主题,清理资源 client.unsubscribe(hwid); } // 绑定消息监听器 client.on("message", handleMessage); client.subscribe(hwid, function (err) { if (err) { // 订阅失败时先清理监听器,再返回错误 client.off("message", handleMessage); return res.status(500).send({ error: "Failed to publish command" }); } // 订阅成功后发布命令 client.publish(hwid, command); }); // 设置超时,防止MQTT无响应导致请求挂起 const timeoutTimer = setTimeout(() => { client.off("message", handleMessage); client.unsubscribe(hwid); res.status(408).send({ error: "Request timeout: No response from target device" }); }, 10000); // 10秒超时,可根据需求调整 // 响应发送完成后清除超时定时器 res.on("finish", () => clearTimeout(timeoutTimer)); }); app.listen(3000, () => { console.log("Server started on port 3000"); });
关键改动说明
- 避免监听器累积:使用命名回调函数
handleMessage,在请求处理完成(收到响应或超时)后,通过client.off()移除该监听器,确保每个请求仅对应一个回调。 - 清理订阅资源:收到响应或超时后,取消对当前
hwid的订阅,避免客户端持续接收无关消息。 - 添加超时保护:防止MQTT长时间无响应导致HTTP请求挂起,提升API健壮性。
- 严格响应匹配:增加
topic === hwid判断,确保仅处理当前请求对应的目标设备响应,避免其他设备消息干扰。
内容的提问来源于stack exchange,提问作者Maxekk
相关产品推荐
相关产品推荐

