首页 > 解决方案 > 无法使用 Azure 函数节点将文件上传到 Azure Blob 存储

问题描述

注意:这里没有问题,问题在于我的 functions.json 脚本文件位置。它指向一个旧的脚本文件。我一指到一个新的,它就开始工作了。

我不确定为什么会发生这种情况,我有一个 try-catch 块,并且该函数永远不会碰到 catch 块,但我尝试上传的图像永远不会出现在容器中。

我是 NODEJS 的新手。由于我无法使用 C# 函数实现相同的功能,因此我决定将其编写在节点中。

问题:Azure 函数服务总线主题触发器,获取消息负载并使用 puppeteer 抓取页面的屏幕截图。缓冲区的输出是缓冲区的形式,我正在尝试将其上传到 Azure 存储 blob。

import { AzureFunction, Context } from "@azure/functions";
import { ServiceBusMessage } from "@azure/service-bus";
import * as puppeteer from 'puppeteer';
import * as BlobServiceClient from "azure-storage";
import { Readable } from 'stream';

const serviceBusTopicTrigger: AzureFunction = async function (context: Context, mySbMsg: ServiceBusMessage): Promise<void> {
    try {
        const promotionId = context.bindingData.userProperties.promotionId;
        context.log('Player Screen Grabber ServiceBus topic trigger function processing message started', promotionId);
        const playerURL = process.env['playerURL'] + promotionId + '/';
        let browser = await puppeteer.launch({ headless: true });
        let page = await browser.newPage();
        await page.goto(playerURL, { waitUntil: 'networkidle2' });
        await page.setViewport({ width: 1920, height: 1080 });
        const screenshotBuffer = await page.screenshot({
            encoding: 'binary'
        });
        await page.close();
        await browser.close();
        const newPlayerScreenShotStream = new Readable({
            read() {
                this.push(screenshotBuffer);
            },
        });
        var fileName = promotionId + ".png";
        context.bindings.fileName = fileName;
        context.bindings.storage = screenshotBuffer;
        context.done();
        context.log('Player Screen Grabber ServiceBus topic trigger function processing message ended', promotionId);
    }
    catch (error) {
        throw error;
    }
};

在此处输入图像描述

标签: node.jsazureazure-functionsserverless

解决方案


根据您提供的信息,您希望在 Azure 函数 blob 存储输出绑定中使用动态名称。如果是这样,我们就不能用context.bindings.<>它来实现它。有关更多详细信息,请参阅此处此处

如果你想实现它,你有以下两种选择。

如果将消息体定义为json,我们可以在函数中直接读取绑定表达式的值

例如

我的留言

在此处输入图像描述

函数.json

{
  "bindings": [
    {
      "name": "mySbMsg",
      "type": "serviceBusTrigger",
      "direction": "in",
      "topicName": "",
      "subscriptionName": "",
      "connection": "MYSERVICEBUS"
    },
    {
      "type": "blob",
      "direction": "out",
      "name": "outputBlob",
      "path": "outcontainer/{fileName}.png",
      "connection": "AzureWebJobsStorage"
    }
  ],
  "scriptFile": "../dist/ServiceBusTopicTrigger1/index.js"
}

功能码

import { AzureFunction, Context } from "@azure/functions";
import * as puppeteer from "puppeteer";

const serviceBusTopicTrigger: AzureFunction = async function (
  context: Context,
  mySbMsg: any
): Promise<void> {
  try {
    context.log("ServiceBus topic trigger function processed message", mySbMsg);
    const promotionId = context.bindingData.userProperties.promotionId;

    const playerURL =
      "https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference-node?tabs=v2";
    let browser = await puppeteer.launch({ headless: true });
    let page = await browser.newPage();
    await page.goto(playerURL, { waitUntil: "networkidle2" });
    await page.setViewport({ width: 1920, height: 1080 });
    const screenshotBuffer = await page.screenshot({
      encoding: "binary",
    });
    await page.close();
    await browser.close();
    context.bindings.outputBlob = screenshotBuffer;
  } catch (error) {
    throw error;
  }
};

export default serviceBusTopicTrigger;

在此处输入图像描述

在此处输入图像描述

  • 使用 Azure Blob 存储 sdk 函数代码
import { AzureFunction, Context } from "@azure/functions";
import * as puppeteer from "puppeteer";
import { BlobServiceClient } from "@azure/storage-blob";
const serviceBusTopicTrigger: AzureFunction = async function (
  context: Context,
  mySbMsg: any
): Promise<void> {
  try {
    context.log("ServiceBus topic trigger function processed message", mySbMsg);
    const promotionId = context.bindingData.userProperties.promotionId;

    const playerURL =
      "https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference-node?tabs=v2";
    let browser = await puppeteer.launch({ headless: true });
    let page = await browser.newPage();
    await page.goto(playerURL, { waitUntil: "networkidle2" });
    await page.setViewport({ width: 1920, height: 1080 });
    const screenshotBuffer = await page.screenshot({
      encoding: "binary",
    });
    await page.close();
    await browser.close();
    // the storage account connection string
    const constr = process.env["AzureWebJobsStorage"];
    const blobserviceClient = BlobServiceClient.fromConnectionString(constr);
    const containerClient = blobserviceClient.getContainerClient("output");
    const blob = containerClient.getBlockBlobClient(`${promotionId}.png`);
    await blob.uploadData(screenshotBuffer);
  } catch (error) {
    throw error;
  }
};

export default serviceBusTopicTrigger;

我的留言 在此处输入图像描述

结果 在此处输入图像描述


推荐阅读