简体   繁体   English

Alexa-app和请求承诺的网络问题

[英]Networking issue with alexa-app and request-promise

I have to be missing something really simple here, but here goes. 我必须在这里遗漏一些非常简单的东西,但是在这里。

I am just now starting to learn Alexa development, and found the alexa-app module which seems to make Alexa programming really straight-forward - except for this networking issue I'm running into. 我现在刚刚开始学习Alexa开发,并找到了alexa-app模块,该模块似乎使Alexa编程变得非常简单-除了我遇到的这个网络问题。

I'm walking through the sample app provided by the team called AirportInfo. 我正在浏览由AirportInfo团队提供的示例应用程序。 The code for the problem area is below: 问题区域的代码如下:

var faaHelper = new FAADataHelper();
faaHelper.requestAirportStatus(airportCode).then(function(airportStatus) {
    var goodMessage = faaHelper.formatAirportStatus(airportStatus);
    console.log(goodMessage);
    res.say(goodMessage).send();
}).catch(function(err) {
    console.log(err.statusCode);
    var prompt = 'I didn\'t have data for an airport code of ' + airportCode;
    console.log(prompt);
    res.say(prompt).reprompt(reprompt).shouldEndSession(false).send();
});
return false;

which in turns calls these functions: 依次调用这些函数:

FAADataHelper.prototype.requestAirportStatus = function(airportCode) {
    return this.getAirportStatus(airportCode).then(
        function(response) {
            console.log('success - received airport info for ' + airportCode);
            return response.body;
        }
    );
};
FAADataHelper.prototype.getAirportStatus = function(airportCode) {
    var options = {
        method: 'GET',
        uri: ENDPOINT + airportCode,
        resolveWithFullResponse: true,
        json: true
    };
    return rp(options);
};

This looks good to me, but when the code runs, the main alexa-app "request" that controls when responses are sent back to the device is returning earlier than expected. 这对我来说似乎很好,但是在代码运行时,控制何时将响应发送回设备的主要alexa-app“请求”返回的时间早于预期。 Instead of a full response payload with the expected weather information for the selected airport, the response is sent back immediately after the return rp(options) call is made. 响应return rp(options)调用后, return rp(options)立即发送回响应,而不是包含所选机场的预期天气信息的完整响应有效负载。 The code that executes in the .then() block in the first code sample runs after the skill has already sent what amounts to an empty response back to Alexa. 在技​​能已将相当于空响应的内容发送回Alexa 之后,将运行第一个代码示例中的.then()块中执行的代码。 This actually crashes Alexa as she says some kind of cryptic message about an error with the skill. 这实际上使Alexa崩溃,因为她说了有关该技能错误的某种隐秘信息。

Here's my server.js code: 这是我的server.js代码:

var AlexaAppServer = require("../index.js");
AlexaAppServer.start({
    server_root: './',
    port: 8080,
    debug: true,
    // Use preRequest to load user data on each request and add it to the request json.
    // In reality, this data would come from a db or files, etc.
    preRequest: function(json, req, res) {
        console.log("preRequest fired");
        json.userDetails = { "name": "Bob Smith" };
    },
    // Add a dummy attribute to the response
    postRequest: function(json, req, res) {
        // look for this output in the log below
        console.log("postRequest fired");
        json.dummy = "text";
    }
});

and here's the debug log showing this condition I'm describing: 这是调试日志,显示了我正在描述的这种情况:

preRequest fired
REQUEST { method: 'GET',
  uri: 'http://services.faa.gov/airport/status/dfw',
  resolveWithFullResponse: true,
  json: true,
  simple: false,
  callback: [Function: RP$callback],
  transform: undefined,
  transform2xxOnly: false }
postRequest fired
REQUEST make request http://services.faa.gov/airport/status/dfw
REQUEST onRequestResponse http://services.faa.gov/airport/status/dfw 200 { date: 'Fri, 24 Mar 2017 05:09:41 GMT',
  server: 'Apache',

  ...

  'access-control-allow-origin': '*',
  'access-control-allow-methods': 'GET, HEAD, OPTIONS',
  'version-requested': 'Any',
  connection: 'close',
  'transfer-encoding': 'chunked',
  'content-type': 'application/json;charset=UTF-8' }
REQUEST reading response's body

...

REQUEST end event http://services.faa.gov/airport/status/dfw
REQUEST has body http://services.faa.gov/airport/status/dfw 517
REQUEST emitting complete http://services.faa.gov/airport/status/dfw
success - received airport info for dfw

Notice where preRequest Fired and postRequest Fired show up relative to success - received airport info for dfw . 请注意,相对于success - received airport info for dfwpreRequest FiredpostRequest FiredpreRequest Fired显示。 Any ideas what I'm doing wrong? 有什么想法我做错了吗? Something mis-configured in my Node environment, or perhaps a bad dependency version? 我的Node环境中配置错误,或者依赖版本不好? I'm suspicious because it fails in my debugger (VS Code) from the Node command prompt, and from Lambda just the same. 我很怀疑,因为它在Node命令提示符下的调试器(VS Code)中失败,而Lambda却是如此。

LINK TO FULL SOURCE CODE: https://github.com/bignerdranch/alexa-airportinfo 链接到完整源代码: https : //github.com/bignerdranch/alexa-airportinfo

I don't understand everything about Promises with regard to Alexa, but I did get this figured out. 对于Alexa,我不了解有关Promises的所有内容,但是我确实知道了这一点。 From the date of your question, there are newer versions of alexa-app-server (3.0.1) and alexa-app (4.0.0) available. 从您提出问题的日期开始,就有可用的alexa-app-server(3.0.1)和alexa-app(4.0.0)的较新版本。 I recently developed a skill using these versions. 我最近使用这些版本开发了一项技能。 alexa-app 2, the version mentioned in alexa-airportinfo, doesn't work with the latest alexa-app-server. alexa-appport 2中提到的版本alexa-app 2不适用于最新的alexa-app-server。

So, first thing to do is to use the latest alexa-app in your code. 因此,首先要做的是在代码中使用最新的alexa-app。 Then, realize that by virtue of using request-promise in FAADataHelper, the code is returning a Promise back to index.js. 然后,意识到通过使用FAADataHelper中的request-promise,代码将Promise返回给index.js。 For this to work you need to return that Promise, instead of the false at the end of the function. 为此,您需要返回该Promise,而不是在函数末尾返回false。

To sum up, I got the latest alexa-app-server, changed the alexa-app version in the airportinfo to the latest, and ran it, getting the same result you did - the response comes back before the rp requests are done. 总而言之,我得到了最新的alexa-app-server,将airportinfo中的alexa-app版本更改为最新版本,然后运行它,得到的结果与您相同-响应在rp请求完成之前返回。 When I changed the code to below, I got the desired result - the requests were done, then the response finished with the speech in. 当我将代码更改为以下代码时,我得到了理想的结果-请求完成,然后响应以语音结束。

app.intent('airportinfo', {
  'slots': {
    'AIRPORTCODE': 'FAACODES'
  },
  'utterances': ['{|flight|airport} {|delay|status} {|info} {|for} {-|AIRPORTCODE}']
},
  function(req, res) {
    //get the slot
    var airportCode = req.slot('AIRPORTCODE');
    var reprompt = 'Tell me an airport code to get delay information.';
    if (_.isEmpty(airportCode)) {
      var prompt = 'I didn\'t hear an airport code. Tell me an airport code.';
      res.say(prompt).reprompt(reprompt).shouldEndSession(false);
      return true;
    } else {
      var faaHelper = new FAADataHelper();
      return faaHelper.requestAirportStatus(airportCode).then(function(airportStatus) {
        console.log(airportStatus);
        res.say(faaHelper.formatAirportStatus(airportStatus)).send();
      }).catch(function(err) {
        console.log(err.statusCode);
        var prompt = 'I didn\'t have data for an airport code of ' + airportCode;
         //https://github.com/matt-kruse/alexa-app/blob/master/index.js#L171
        res.say(prompt).reprompt(reprompt).shouldEndSession(false).send();
      });
      // return false;
    }
  }
);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM