si 我的简单 expressjs API 有一个问题,它接受一个包含计算机 ID 的有效负载和一个将在目标计算机上执行的命令。 API 有效,至少向 mqtt 服务器发送消息有效,但接收它们时出现问题。在“onmessage”事件监听器上有一个问题,第一次运行此代码时有效,但是当我尝试在同一台电脑上执行另一个命令或什至第二次执行同一命令时,代码崩溃并给我这个错误:
throw new ERR_HTTP_HEADERS_SENT('set');
^
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
代码如下:
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]: Succesfully 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}`);
client.subscribe(hwid, function (err) {
if (!err) {
client.publish(hwid, command);
} else {
res.status(500).send({ error: "Failed to publish command" });
}
});
client.on("message", function (topic, message) {
if (command == message.toString()) {
return;
} else {
res.send({ hwid: topic, content: message.toString() });
}
});
});
app.listen(3000, () => {
console.log("Server started on port 3000");
});
我已经尝试用命令和消息删除这个 if 语句,但我需要这个语句,所以我不会收到与我发送到服务器的消息相同的消息,我只想要来自我使用 hwid 选择的 pc 的响应
MQTT 客户端真的不是这样工作的
首先,您正在泄漏
client.on('message',...)
处理程序。每次调用 put
处理程序时,它都会添加另一个版本的回调。每个版本都将保留 res
对象的本地副本,因此将尝试回复已经完成的 HTTP 请求以获取后续消息。
尝试将异步协议 (MQTT) 映射到同步协议 (HTTP) 需要详细了解不同的模型。这是可能的,但您需要通过在响应中返回的已发布消息上传递一个 I'd 来保留一个飞行请求列表,以便正确的响应可以链接到正确的 HTTP 会话。
我的项目中有一个例子:
https://github.com/hardillb/node-red-contrib-googlehome-web/blob/master/action-route.js#L41