Node.js 错误:Can';t在发送邮件后设置邮件头。刷新get请求后收到错误

Node.js 错误:Can';t在发送邮件后设置邮件头。刷新get请求后收到错误,node.js,express,mqtt,Node.js,Express,Mqtt,以下代码在第一次执行时按预期工作。第二次执行失败,出现以下错误: 错误:发送邮件后无法设置邮件头。 基本上,我试图从一系列已发布的mqtt主题返回一条消息。我试过几种方法来做到这一点,但我对这种行为感到茫然。下面的代码显示了一个使用承诺的尝试,详见MDN文章。我还尝试使用async/await(如果需要,我也可以发布此代码) 概念 get请求从网页到达,这将触发一条mqtt消息发布到本地代理。另一个端点正在侦听此主题。在这种情况下,一个树莓皮与连接的网络摄像头。当rpi完成它的工作并发布一条返回

以下代码在第一次执行时按预期工作。第二次执行失败,出现以下错误:
错误:发送邮件后无法设置邮件头。

基本上,我试图从一系列已发布的mqtt主题返回一条消息。我试过几种方法来做到这一点,但我对这种行为感到茫然。下面的代码显示了一个使用承诺的尝试,详见MDN文章。我还尝试使用async/await(如果需要,我也可以发布此代码)

概念
get请求从网页到达,这将触发一条mqtt消息发布到本地代理。另一个端点正在侦听此主题。在这种情况下,一个树莓皮与连接的网络摄像头。当rpi完成它的工作并发布一条返回消息时,主题被接收,返回消息中包含一个url作为它的数据。初始mqtt发布服务器正在侦听此响应并激发res.json()作为响应。
这是第一次,当我刷新网页时,它失败了,发送后会出现“不能”标题。如何重置res?看来情况就是这样

punchitRoute.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;
server.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);
我的猜测是,对于使用express的请求,我缺少了一个基本的生活事实。

提前感谢您的指导。

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

关于
client.on('message',…)
的事件处理程序的第二条注释为我提供了查看事件循环所需的提示

这里的想法是使用来自get请求的mqtt从网络摄像头捕捉图像。get请求进入express服务器,触发对名为“返回”的主题的订阅。,并发布到名为“日出”的主题。,消息为“单击”

本地网络上有一个单独的端点,正在侦听本地mqtt代理(两者都与express服务器共享),该代理正在侦听'sunrise'主题。将映像保存到S3存储桶中并将映像的url作为消息发送回运行get请求的服务器后,此端点广播的“返回”。mqtt函数工作得很好,我遇到的问题是响应事件没有在响应结束时终止。对于这项工作,有几件事必须改变

  • 将res.send移动到client.on之后调用的函数中(这没有完全起作用,它允许发送,但仍然返回错误)
  • 添加了事件发射器,以查看一次又一次触发了哪些事件(这使我对正在发生的事情有了一些了解,但仍然没有删除错误)
  • 研究了其他mqtt库(最终使用异步mqtt)
  • 在res.send函数之后添加了client.unsubscribe,用于两个主题(这没有效果)
  • 终于找到了答案,这让我意识到,在这段时间里,我本可以给客户打个电话。一次 下面是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');
            }
        })
    });
    
    punchitRoute.get('/',异步函数(req,res){
    //正在添加事件列表器“发送”
    mqEvent.on('send',function()){
    log('added send');
    });
    让sendit=函数(url){
    'send',//emmitting'send'
    资源状态(200)。发送(
    ''+
    “打!”+
    “”+
    'name:garfield
    time:'+moment(Date.now()).tz(“America/Louisville”).format(“MM-DD-YYYY”); } client.subscribe('returned',function(){ console.log('subscribed'); }); client.publish('sunrise','click'); //将此更改为。一次,不再出现错误 等待客户端。一次('message',异步函数调用(主题,url){ 试一试{ mqEvent.on('message',function()){ console.log('added message'); }); sendit(url.toString()); //控制台日志(res); 客户端。取消订阅('返回',()=>{ console.log(“取消订阅”); }); 客户端。取消订阅('sunrise',()=>{ console.log(“取消订阅发布”); }); //清除发送事件侦听器 mqEvent.removeAllListeners('send'); log(mqEvent.listenerCount('send')); //清除消息事件侦听器 mqEvent.removeAllListeners('message'); }捕获(e){ 控制台日志(e); console.log('error'); } }) });

    希望这能帮助其他人面对类似的问题

    首先,您的
    img()
    函数从不调用
    resolve()
    来解决它的承诺。其次,每次调用
    img()
    ,您都会为
    客户端添加另一个事件处理程序。on('message',…)
    。这些信息会堆积起来,你会有重复的信息,你会尝试多次回复同一条信息。通常情况下,承诺与事件处理程序并不匹配,因为如果函数被多次调用,则会出现排序问题,但如果要尝试以这种方式使用承诺,则必须在事件处理程序触发后删除它。即使如此,仍然有一些问题需要解决。感谢您的回复。在这种情况下使用async/await更好吗?老实说,您的代码太混乱了,我真的无法建议您应该做什么。您需要提供您试图完成的任务的完整描述(用文字,而不是代码),以便我们可以从头开始建议最好的实现方式
    async/await
    不会修复我所评论的任何东西。混乱是一种很好的表达方式。上面的代码是一个错误,当我最终意识到我不是cal时,我复制的文件没有经过测试就被编辑了