node.js - Azure Function App 对 Webhook 的初始响应
问题描述
我的函数应用中有一个 HTTP 触发函数 - 它由 Azure 逻辑应用中的 webhook 连接器调用。Webhook 在逻辑应用程序中的工作方式是它们需要初始响应,例如"status:200"
使逻辑应用程序进入睡眠状态,然后在“工作”完成时callbackURL
调用,然后逻辑应用程序恢复工作。我的问题是响应我的函数应用程序的初始响应。
如果您在 2 分钟内未使用 status:2** 响应 webhook,则 webhook “重试”会启动函数应用的新实例,这显然是有问题的。
所以我的代码看起来像这样
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
}
我尝试context.res = { status:200}
在 try 块中添加并尝试创建一个context.res = {status:200}
内部的单个函数,但是这些都不起作用。
如果我的函数运行不到 2 分钟,那么显然 webhook 不会重试,但是当它确实需要超过 2 分钟时它会失败。
我尝试基于本文中的“Webhook”设计进行构建
这些是我尝试过的组合:
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
解决方案
考虑创建第二个函数来处理长时间运行的操作并更改当前函数以将请求放入队列并立即返回。
您的 Web 挂钩命中的 HTTP 触发器:
函数.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
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 }
});
};
执行处理的队列触发器:
函数.json
{
"bindings": [
{
"name": "item",
"type": "queueTrigger",
"direction": "in",
"queueName": "process",
"connection": "AzureWebJobsStorage"
}
]
}
index.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);
});
}
请注意,我在request
这里使用的是外部依赖项,您必须将其添加到您package.json
的 .Node 中,但 Node 内置的 HTTP 客户端也可以正常工作。
推荐阅读
- c++ - 如何从另一个 qml 文件更改标签文本?
- python - igraph 无法在 Windows 上的 Spyder IDE 上运行
- android - 我为我的 json 帖子和响应设置了进度条。但它没有显示
- java - Android - 隐藏/删除边距以及隐藏 RecyclerView 的项目
- mysql - 在mysql中将日期表转换为年份
- python-3.x - 烧瓶测试:preprocess_request()、dispatch_request()
- python - 为什么类变量的类型是超类的类型?
- awk - 打印出现在 awk 中的 file2 中的 file1 的字符串
- vim - 用 Vim Goyo 写作时有没有办法去除波浪线?
- javascript - 如果您 json_encode 返回已经是 JSON 的 api 数据会发生什么