【问题标题】:Sending multiple responses with Express.js per request每个请求使用 Express.js 发送多个响应
【发布时间】:2017-11-03 13:20:18
【问题描述】:

我正在学习 node js,并且正在使用 Dialogflow 开发机器人。我想建立一个简单的机制:

  • 第 1 步:dialogflow 发送带有 param1 参数的 POST 请求
  • 第 2 步:我的应用程序通过 JSON 形式的 POST 响应返回一条等待消息(例如:“您的请求正在处理中”)
  • 第 3 步:我从 REST API 检索数据
  • 第 4 步:使用 JSON 响应 DialogFlow 的 Webhood

我的问题(第 4 步)是我无法为同一个请求发送两个响应,并且我收到以下错误消息:

2017-11-03T12:45:00.774506+00:00 app[web.1]: Error: Can't set headers after they are sent.
2017-11-03T12:45:00.774507+00:00 app[web.1]:     at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:356:11)
2017-11-03T12:45:00.774508+00:00 app[web.1]:     at ServerResponse.header (/app/node_modules/express/lib/response.js:767:10)
2017-11-03T12:45:00.774508+00:00 app[web.1]:     at ServerResponse.send (/app/node_modules/express/lib/response.js:170:12)
2017-11-03T12:45:00.774509+00:00 app[web.1]:     at searching.then (/app/index.js:89:21)
2017-11-03T12:45:00.774509+00:00 app[web.1]:     at process._tickCallback (internal/process/next_tick.js:109:7)

这是我的代码:

const express = require('express');
const bodyParser = require('body-parser');

//middleware 
app.use(bodyParser.urlencoded({
    extended: true
}));
app.use(bodyParser.json());

app.post('/webhook', function (req, res, next) {
    if (req.body.result && req.body.result.parameters && req.body.result.parameters.param1) {

        // First response 
        var speechObject = {             
            speech: "your request is being processed",
            displayText: "your request is being processed",
            source: 'webhook-nodejs-api'}
        var json_1 = JSON.stringify(speechObject)
        res.send(json_1)

        // Second response

            searching_data_from_api().then(() => {
                console.log("return second response JSON")
                var dataObject = { type_pizza: "4 formages" }
                var eventObject = { name: "pizza_est_prete", data: dataObject }
                var json_2 = JSON.stringify({
                    followupEvent: eventObject
                })
                res.send(json_2);
                return res.end()
            }).catch(error => {
                console.log(error)
            })
    } else {
        var speech = "There is a problem. Try Again"
        return res.json({
            speech: speech,
            displayText: speech,
            source: 'webhook-nodejs-api'
        })
        console.log("There is a problem. Try Again")
    }
})

app.listen((process.env.PORT || 8000), function () {
    console.log("Server up and listening");
});

我的问题是,如何发送第二个答案?我尝试: - res.write (JSON.stringify (data1)) - res.write (JSON.stringify (data2)) - res.end()

但它没有用。感谢您的帮助!

【问题讨论】:

  • 为什么不连接 2 个响应并发送最终响应?
  • 您不能使用 HTTP 向单个请求发送多个响应,这是协议的基本概念之一:一个请求,一个响应。处理请求需要多长时间(得到最终结果)?您如何提交请求(新页面加载或 Ajax)?
  • 是的,谢谢您的回答。问题是数据提取需要超过 5 秒,如果我的机器人在 1 秒内没有收到数据,它会返回错误(我无法在 DialogFlow 级别修改计时器)。我不知道如何设置异步处理以通过另一种方式发送第二个响应。

标签: javascript json node.js express dialogflow-es


【解决方案1】:

如果您使用 Dialogflow 的内置集成,则只能在直接响应用户输入时发出响应,因此无法对单个请求做出两次响应。

如果您决定不使用内置集成,则可以编写一些代码,将原始“您的请求正在处理”响应发送给用户,执行所需的处理,然后发送后续消息自己回应。您将执行以下操作:

  • 处理来自用户使用的任何平台的传入请求
  • 通过/query API 端点将用户的查询发送到 Dialogflow
  • 分析来自 Dialogflow 的响应以确定匹配的意图。如果它是需要调用延迟处理的意图,请调用它。
  • 向用户发送“您的请求正在处理中”。
  • 延迟处理完成后,将响应发送给用户。

请务必注意,您将自己向用户发送最终响应;不会涉及 Dialogflow。

【讨论】:

  • 感谢您的回复@Dan Imrie-Situnayake 这正是我所做的。我在这里使用 Dialogflow 团队提出的功能github.com/dialogflow/dialogflow-nodejs-client/tree/master/… 我遇到的问题是我无法从 DialogFlow 中的 facebook 消息中获取 Sender ID 并将其作为参数发送到我的 Weebhook(因为我使用 FB Messenger 作为通道) 通过结果 .originalRequest.data 发送。任何的想法 ?感谢您的帮助
  • 如果您自己与 Facebook 进行集成,然后调用 /query 端点,则 Facebook 请求数据将不会出现在 webhook 请求中,因为 Dialogflow 从未直接与 Facebook 交互。要将此信息获取到 webhook,您需要将其添加到您对 /query 端点的请求中。有关如何操作的信息,请参阅此 StackOverflow 答案:stackoverflow.com/questions/47115004/…
  • 好的,非常感谢。那么将具体数据从我们的 webhook 发送到 dialogflow 的唯一方法是创建一个通用上下文?那么“originalRequest”呢?
  • 糟糕,我忘了在我的回答中包含它 :) 是的,当您调用 /query 时,您可以在 originalRequest 字段中提供一个对象,它将在 webhook 中可用。跨度>
【解决方案2】:

你应该看看followup events

基本上,您需要立即响应,然后加载数据,并将它们发布到您的机器人。

看到这个:https://discuss.api.ai/t/fulfilment-using-webhook-takes-time-to-get-the-data/3726/7

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-07
    • 2017-10-12
    • 2015-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多