外部サービス

Blazor ServerでAzure FunctionsのQueueトリガーを使う手順

azure-functions-queue-trigger

Azure Functions は、通常のメソッドと同じように使用する Http トリガーが一番有名ですが、この記事では Queue トリガーを使います。

Queue トリガーは実行した直後にレスポンスを求めるものではなく、多少時間がかかっても実行されれば OK とする処理に向いています。

例えばメール送信などが Queue トリガーに向いているので、この記事では簡易的な実装方法をまとめました。

実際にメール送信はしませんが、手順は参考になるはずです。

また、Queue トリガーを動かすには通常 Azure Storage Account の作成が必要になりますが、作成せずにローカルで動かすのエミュレーターについても解説しているので、ローカル環境で動作確認ができます。

それでは、さっそく見ていきましょう。

Azure Functions の Queue トリガーを使うための準備

各プロジェクトの作成

まずは、Blazor Server のプロジェクトを作成します。

azure-functions-queue-trigger

次に、作成したソリューションに対して Azure Functions の Queue トリガーのプロジェクトを追加します。

Connection String は AzureWebJobsStorage としておくことで、設定ファイルが初期状態のままで使えます。

あとは関数名とキュー名を適当に入力してください。

azure-functions-queue-trigger

続いて、Blazor 側と Azure Functions 側で共通して使用する Shared プロジェクトを作成します。

名前は好きなもので構いません。

azure-functions-queue-trigger

Queue に渡すクラスを作成

共通のプロジェクトに、Queue 渡したい情報を格納しておくクラスを作成します。

今回は、タイトルと本文を格納できるクラスにしました。

SendEmailPayload.cs
namespace AzureFunctions.Shared;

public class SendEmailPayload
{
    public string Title { get; init; }
    public string Body { get; init; }

    public SendEmailPayload(string title, string body)
    {
        this.Title = title;
        this.Body = body;
    }
}

Queue トリガーの修正

Queue トリガーを少し修正して、SendEmailPayload を引数で受け取るように修正します。

また、ログ内容にタイトルと本文の内容を出力するようにしました。

SendEmail.cs
using System;
using AzureFunctions.Shared;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Logging;

namespace AzureFunctions;

public class SendEmail
{
    [FunctionName("SendEmail")]
    public void Run([QueueTrigger("send-email", Connection = "AzureWebJobsStorage")] SendEmailPayload payload, ILogger log)
    {
        log.LogInformation($"Title: {payload.Title} | Body: {payload.Body}");
    }
}

NuGet パッケージの追加

Blazor のプロジェクトに Azure.Storage.Queues のパッケージを追加します。

これにより、Blazor で Queue トリガーを送信できるようになります。

azure-functions-queue-trigger

Queue に送るためのサービスクラスを作成

Queue に送るためのサービスクラスを Blazor 側のプロジェクトに作成します。

キューの名前と渡したいクラスを受け取って、キューを送るシンプルなものです。

QueueService.cs
using System;
using Azure.Storage.Queues;

namespace BlazorQueueTrigger.QueueTriggers;

public class QueueService
{
    public QueueService()
    {
    }

    public static void SendMessage<T>(string queueName, T payload)
    {
        var options = new QueueClientOptions { MessageEncoding = QueueMessageEncoding.Base64 };
        var queueClient = new QueueClient("UseDevelopmentStorage=true", queueName, options);
        queueClient.CreateIfNotExists();
        if (queueClient.Exists())
        {
            var data = BinaryData.FromObjectAsJson(payload);
            queueClient.SendMessage(data);
        }
    }
}

接続文字列は環境変数から取得するのが望ましいですが、今回は動作確認を目的としているため、固定としました。

クラウド上で実行する場合はあらかじめ Storage Account にキューの名前を登録しておく必要がありますが、CreateIfNotExists を呼ぶことで、登録されていなければ自動で登録してくれるようになります。

DI の追加

追加した QueueService は DI をしておかないとエラーになるので、Program.cs に AddSingleton を追記しておきましょう。

Program.cs
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using BlazorQueueTrigger.Data;
using BlazorQueueTrigger.QueueTriggers;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddSingleton<WeatherForecastService>();
builder.Services.AddSingleton<QueueService>();

var app = builder.Build();

// 中略

画面から Queue を送信する

最後に、トップ画面でキューを送信するボタンを用意すれば準備完了です。

Pages/Index.razor
@page "/"
@using QueueTriggers
@using AzureFunctions.Shared
@inject QueueService QueueService

<button class="btn btn-primary" @onclick="SendEmail">Send Email</button>

@code {
    private void SendEmail()
    {
        var payload = new SendEmailPayload("タイトル", "本文");
        QueueService.SendMessage("send-email", payload);
    }
}

 

Queue トリガーをデバッグするための環境構築

Azure Storage Explorer のインストール

ここまでで、Blazor の画面にボタンを用意して、そこから Queue トリガーを送信するよう実装しました。

しかし、Azure Storage Explorer を使うことでも、Queue トリガーを送信することができます。

公式サイトよりダウンロードしてインストールするだけなので簡単です。

あとで実際に使ってみます。

Azure Functions Core Tools のインストール

Azure Functions をローカルで動かすときに必要なツールです。

公式ドキュメントを参考にインストールしてみてください。

Azurite のインストール

公式ドキュメントによると、ローカルでデバッグするには Visual Studio 2022 をデバッグ実行すればよいはずです。

しかし私の Mac の場合は Azurite をインストールしないとうまく動かなかったので、インストールしていきます(Windows の人はスキップでもいいかもしれません)。

私の場合はグローバルにインストールできなかったため、適当なフォルダにインストールしました。

$ cd {インストールしたいフォルダ}
$ npm i azurite

これで azurite コマンドが使用できるようになったので、以下のコマンドを実行してみましょう。

ローカルで Queue トリガーを実行できるようになりました。

$ npx azurite --location azurite
Azurite Blob service is starting at http://127.0.0.1:10000
Azurite Blob service is successfully listening at http://127.0.0.1:10000
Azurite Queue service is starting at http://127.0.0.1:10001
Azurite Queue service is successfully listening at http://127.0.0.1:10001
Azurite Table service is starting at http://127.0.0.1:10002
Azurite Table service is successfully listening at http://127.0.0.1:10002

複数スタートアッププロジェクトの設定

Azure Functions を受け付けるプロジェクトと、Blazor を起動するプロジェクトの2つを起動するように、設定を追加しましょう。

Mac の場合は、ソリューションのプロパティから変更できます。

azure-functions-queue-trigger

いま追加した構成で起動するように、Visual Studio の設定を変更しておきます。

azure-functions-queue-trigger

動作確認

事前準備

事前準備として、Azurite を起動させておく必要があります。

まだ起動していない人は、以下のコマンドで起動しておきましょう。

$ npx azurite --location azurite
Azurite Blob service is starting at http://127.0.0.1:10000
Azurite Blob service is successfully listening at http://127.0.0.1:10000
Azurite Queue service is starting at http://127.0.0.1:10001
Azurite Queue service is successfully listening at http://127.0.0.1:10001
Azurite Table service is starting at http://127.0.0.1:10002
Azurite Table service is successfully listening at http://127.0.0.1:10002

実行したパスの下に azurite フォルダを作成して、その下にファイルが作成されます。

先ほども書きましたが、Windows の人は不要かもしれません。

Visual Studio をデバッグ実行して、ターミナルに以下のようなログが出れば、Azure Functions が実行できる状態になっています。

Azure Functions Core Tools
Core Tools Version:       4.0.4653 Commit hash: N/A  (64-bit)
Function Runtime Version: 4.6.1.18388

[2022-07-24T11:06:08.587Z] Found BlazorQueueTrigger/AzureFunctions/AzureFunctions.csproj. Using for user secrets file configuration.

Functions:

        SendEmail: queueTrigger

For detailed output, run func with --verbose flag.
[2022-07-24T11:06:17.304Z] Host lock lease acquired by instance ID '000000000000000000000000DB4EE21E'.

Blazor の画面から Queue を送信する

Blazor のトップ画面にボタンを配置しているので、ボタンを押してみましょう。

azure-functions-queue-trigger

ボタンを押すと、ターミナルに以下のようなログが出力されれば成功です。

正常に Queue トリガーを実行できたことが確認できました。

[2022-07-24T11:09:00.774Z] Executing 'SendEmail' (Reason='New queue message detected on 'send-email'.', Id=d94c9ee9-8fba-43eb-8345-50ae84ec95ae)
[2022-07-24T11:09:00.775Z] Trigger Details: MessageId: fcf83c6e-8e2e-491d-971a-9591df74cae3, DequeueCount: 1, InsertionTime: 2022-07-24T11:08:58.000+00:00
[2022-07-24T11:09:00.787Z] Title: タ イ ト ル  | Body: 本 文                                                      
[2022-07-24T11:09:01.087Z] Executed 'SendEmail' (Succeeded, Id=d94c9ee9-8fba-43eb-8345-50ae84ec95ae, Duration=338ms)

Azure Storage Explorer から Queue を送信する

わざわざ画面にボタンを置いて実行するのも大変なので、手軽に実行したい場合は Azure Storage Explorer を使用しましょう。

Azurite が実行されている状態で、[ローカルで接続済み] -> [ストレージアカウント] -> [エミュレーター 規定のポート] の中を開いて、「send-email」のキューを追加します。

その後、[メッセージを追加] のメニューを選択してください。

azure-functions-queue-trigger

メッセージとは、Queue トリガーに渡したい引数です。

今回は SendEmailPayload の中身を渡したいので、次のように手書きで JSON を記載しましょう。

azure-functions-queue-trigger

手書きするのが面倒だと思うので、コピペできる文字列も用意しておきます。

{
    "Title": "テストタイトル",
    "Body": "テスト本文"
}

これで OK をすると、キューが実行されて Blazor の画面から実行したときと同様のログが出力されます。

[2022-07-24T11:15:05.449Z] Executing 'SendEmail' (Reason='New queue message detected on 'send-email'.', Id=ad59aa26-d694-4be1-ada6-1756e1cefb26)
[2022-07-24T11:15:05.450Z] Trigger Details: MessageId: c1ecd166-8ea0-46af-86f8-8e657fce59ee, DequeueCount: 1, InsertionTime: 2022-07-24T11:15:04.000+00:00
[2022-07-24T11:15:05.454Z] Title: テ ス ト タ イ ト ル  | Body: テ ス ト 本 文                                                                  
[2022-07-24T11:15:05.484Z] Executed 'SendEmail' (Succeeded, Id=ad59aa26-d694-4be1-ada6-1756e1cefb26, Duration=51ms)

どちらで実行した場合も、ブレイクポイントを置いてデバッグ実行もできるので、試してみてください。

最後に

Blazor Server で Azure Functions の Queue トリガーを使う手順について解説しました。

簡易的な確認ですが、ミニマムで実行する手順は参考になったと思います。

この記事を参考に、ぜひ試してみてください。

Blazor の書籍も好評発売中!
blazor-book

入門編から EC サイトを作る応用編まで、Blazor の本を3冊執筆しました。

私が1年以上かけて学習した内容をすべて詰め込んでいるので、さらにステップアップしたい方はぜひご覧ください。