简体   繁体   English

Azure Function App 对 Webhook 的初始响应

[英]Initial Response to Webhook from Azure Function App

I have a HTTP triggered function inside my function app - it is invoked by the webhook connector in Azure Logic Apps.我的函数应用中有一个 HTTP 触发的函数 - 它由 Azure 逻辑应用中的 webhook 连接器调用。 The way webhooks work in Logic Apps is they need the initial response like "status:200" which puts the Logic App to sleep and then when the "work" is done the callbackURL is invoked and then the Logic App resumes work. Webhooks 在逻辑应用程序中的工作方式是,它们需要初始响应,例如"status:200" ,它使逻辑应用程序进入睡眠状态,然后在“工作”完成时调用callbackURL ,然后逻辑应用程序恢复工作。 My problem is responding with that initial response from my function app.我的问题是响应我的函数应用程序的初始响应。

If you don't respond to the webhook with a status:2** within 2 minutes then the webhook "retries" which starts a new instance of the function app and that is obviously problematic.如果您没有在 2 分钟内以 status:2** 响应 webhook,则 webhook 会“重试”,这会启动函数应用程序的新实例,这显然是有问题的。

So my code looks something like this所以我的代码看起来像这样

try 
{ 
     await function1() // this function runs more than 2 minutes
}
catch(err)
{
     context.log(err)
}
finally
{
     await function2() // this function returns to LogicApp via callbackurl
}

I have tried adding context.res = { status:200} in the try block and have tried creating an individual function that has context.res = {status:200} inside, however none of those work.我尝试在 try 块中添加context.res = { status:200}并尝试创建一个内部具有context.res = {status:200}的单个函数,但是这些都不起作用。

If my function runs under 2 minutes then obviously the webhook doesn't retry, however when it does take over 2 minutes it fails.如果我的函数在 2 分钟内运行,那么显然 webhook 不会重试,但是当它花费超过 2 分钟时它会失败。

I tried to build based on the "Webhook" design from this article我尝试基于本文中的“Webhook”设计进行构建

Calling Long Running Functions Azure 调用长时间运行的函数 Azure

These are the combinations I have tried:这些是我尝试过的组合:

try {
    context.bindings.res = {status:202}
    await function1()
}

try {
    context.res = {status:202}
    await function1()
}

try {
    await initialResponse(context)// function that has context.res={status:202} inside
    function1()
}

try {
    context.res = {status:202}
    context.done()
    await function1()
} // I added @UncleDave 's suggestion as well

try {
    await initialResponse(context)
    function1()
}
async function initialResponse(context)
{
    context.res = {status:202}
    context.done()
} // this attempt also just ended the function

Consider creating a second function to handle the long running operation and change your current function to throw the request on to a queue and immediately return.考虑创建第二个函数来处理长时间运行的操作并更改当前函数以将请求放入队列并立即返回。

The HTTP Trigger hit by your web hook:您的网络钩子命中的 HTTP 触发器:

function.json函数.json

{
  "bindings": [
    {
      "authLevel": "anonymous", // Don't do this - demonstration only.
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    },
    {
      "type": "queue",
      "direction": "out",
      "name": "queue",
      "queueName": "process",
      "connection": "AzureWebJobsStorage"
    }
  ]
}

index.js索引.js

module.exports = function (context, req) {
  context.log('Started processing a request.', req);

  context.done(null, {
    res: { status: 202 },
    queue: { callbackUrl: req.body.callbackUrl, data: req.body.data }
  });
};

The Queue Trigger that does the processing:执行处理的队列触发器:

function.json函数.json

{
  "bindings": [
    {
      "name": "item",
      "type": "queueTrigger",
      "direction": "in",
      "queueName": "process",
      "connection": "AzureWebJobsStorage"
    }
  ]
}

index.js索引.js

module.exports = async function (context, item) {
    context.log('JavaScript queue trigger function started to process work item.', item);

    const data = await process(item.data);

    const request = require('request');

    await request.post(item.callbackUrl, { body: data, json: true });
};

function process(data) {
    // Some long running operation.
    return new Promise(resolve => {
        setTimeout(() => resolve({ a: 'b', c: 'd' }), 5000);
    });
}

Note that I'm using request here, which is an external dependency you'll have to add to your package.json , but Node's built in HTTP Client will work just as well.请注意,我在这里使用了request ,这是您必须添加到package.json的外部依赖项,但 Node 内置的 HTTP 客户端也可以正常工作。

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

相关问题 第一次 webhook 响应后的 Azure Http 触发函数挂断套接字 - Azure Http Trigger function Hangup socket after the first webhook response 我在 Dialogflow 上的 webhook 没有响应 - No response from my webhook on Dialogflow 从node.js中的webhook发送不同的响应(Dialogflow) - Send different response from webhook in nodejs (Dialogflow) Azure 表存储节点JS function app返回响应为空 - Azure table storage Node JS function app return response empty 在Azure上更改NodeJS应用的初始文件位置 - Changing the initial file location of NodeJS app on Azure cMalformedResponse:Webhook错误(206)同时看似有效的Webhook响应-Node.js中对Google Dialogflow应用的操作 - cMalformedResponse: Webhook error (206) whilst a seemingly valid webhook response - Actions on Google Dialogflow app in Node.js 无法从 NodeJS 中的 Azure httpTriggered Function 获取响应数据 - Can not get the data in response from Azure httpTriggered Function in NodeJS 如何在Azure函数的响应中添加自定义http标头 - How to add custom http header in response from Azure function Azure函数httptrigger无法从SQL Server请求返回响应 - Azure function httptrigger not returning response from SQL Server request 格式错误的响应:从 dialogflow Web 挂钩获取响应时出现 Webhook 错误 - Malformed Ressponse: Webhook error on getting response from dialogflow web hook
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM