错误:发送标头后无法设置标头。 刷新 GET 请求后收到错误



以下代码在第一次执行时按预期工作。第二次通过它失败并显示以下错误:
Error: Can't set headers after they are sent.
基本上,我正在尝试从一系列已发布的 mqtt 主题返回一条消息。我已经尝试了几种方法来做到这一点,但对这种行为感到茫然。下面的代码显示了使用本 MDN 文章中详述的承诺的尝试。我还尝试使用异步/等待(如果需要,我也可以发布此代码(。

概念
get 请求从网页到达,这会触发将 mqtt 消息发布到本地代理。 单独的终结点正在侦听本主题。在这种情况下,带有连接网络摄像头的树莓派。收到主题后,rpi 会执行其操作并发布带有 url 作为数据的返回消息。初始 MQTT 发布服务器正在侦听此响应,并触发 res.json(( 作为响应。
这第一次有效,当我刷新网页时,它在发送后失败并显示无法标题。如何重置 res?看来情况确实如此。

打孔路线.js

const express = require('express');
const punchitRoute = express.Router();
const mqtt = require('mqtt');
const client = mqtt.connect('mqtt://192.168.88.54:1883');
client.subscribe('returned', function(){
console.log('subscribed');
})
async function img(){
return new Promise(resolve =>{ client.on('message', function(topic, url){
const message = {
url: url.toString(),
name: "garfield",
date: Date.now()
}
return message;
})
})
}
punchitRoute.get('/', async function(req, res){
const mess = await img();
console.log(mess);
res.json(mess);
});
module.exports = punchitRoute;

服务器.js

const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const punchit = require('./routes/punchitRoute');

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended:false })); 
app.get("/", (req, res) => {
res.json({
name: "Express application",
message: "welcome to punchit"
})
});
app.use('/api/punchit', punchit);
const PORT = process.env.PORT || 6040;
app.listen(PORT);
console.log('server started on: ', PORT);

我的猜测是,我错过了一个关于使用快递的请求的基本事实。
提前感谢您的任何指导。

感谢jfriend00为我指出正确的方向。首先,发布的代码完全不正确。我对此感到非常困惑,随后重命名了文件 punchitRoute 文件以继续以不同的方法处理它,但忘记重命名服务器中所需的文件.js!这是一个愚蠢的错误。

关于client.on('message', ...)事件处理程序的第二条评论给了我查看事件循环所需的提示。

这里的想法是使用 mqtt 从网络摄像头捕捉图像 从获取请求。get 请求进入快速服务器,触发对名为"返回"的主题的订阅,并使用"click"消息发布到名为">sunrise">的主题。

本地网络上有一个单独的端点,正在侦听正在侦听"日出">主题的本地 mqtt 代理(两者都与快递服务器共享(。在将映像保存到 S3 存储桶后,此终端节点广播的"返回">,并将映像的 URL 作为消息发送回运行 get 请求的服务器。mqtt 函数运行良好,我遇到的问题是响应事件在响应结束时未终止。对于这项工作,必须改变几件事。

  1. 将res.send移动到在client.on之后调用的函数中(这并不完全有效,它允许发送发生,但仍然返回错误(
  2. 添加了事件发射器以查看一遍又一遍地触发了哪个事件(这让我对正在发生的事情有一定的了解,但仍然没有消除错误(
  3. 研究了其他MQTT库(最终保留了Async-MQTT(
  4. 在 res.send 函数之后为这两个主题添加了 client.取消订阅(这没有效果(
  5. 终于找到了这个答案,它帮助我意识到我一直可以打电话给 client.once!

下面是 GET 请求的代码:

punchitRoute.get('/', async function(req, res){
//adding event listner 'send'
mqEvent.on('send', function(){
console.log('added send');
});
let sendit = function(url){
'send', //emmitting 'send'
res.status(200).send(
'<img src='+url.toString()+' />'+
'<h1>PUNCHED!</h1>'+
'<p>'+
'name: garfield <br/> time: '+moment(Date.now()).tz("America/Louisville").format('MM-DD-YYYY'));
}
client.subscribe('returned', function(){
console.log('subscribed');
});
client.publish('sunrise', 'click');
//changed this to .once and no more errors
await client.once('message', async function callout(topic, url){
try {
mqEvent.on('message', function(){
console.log('added message');
});
sendit(url.toString());
// console.log(res);
client.unsubscribe('returned', ()=>{
console.log('unsubscribed');
});
client.unsubscribe('sunrise', ()=>{
console.log('unsubscribed publish');
});
//clearing out the send event listeners
mqEvent.removeAllListeners('send');
console.log(mqEvent.listenerCount('send'));
//clearing out the message event listeners
mqEvent.removeAllListeners('message');
} catch(e){
console.log(e);
console.log('error');
}
})
});

希望其他人可以面临类似的问题。

相关内容

最新更新