次の方法で共有


Azure Functions における SignalR Service の出力バインド

SignalR 出力バインドを使用して、Azure SignalR Service で 1 つ以上のメッセージを送信します。 次の宛先にメッセージをブロードキャストできます。

  • 接続されているすべてのクライアント
  • 指定したグループ内の接続済みクライアント
  • 特定のユーザーに対して認証された接続されているクライアント

出力バインドを使用すると、グループを管理することもできます。たとえば、グループへのクライアントまたはユーザーの追加、グループからのクライアントまたはユーザーの削除などです。

セットアップと構成の詳細については、概要に関するページをご覧ください。

すべてのクライアントにブロードキャストする

A C# 関数は、次の C# モードのいずれかを使用して作成できます。

  • 分離されたワーカー モデル: ランタイムから分離されたワーカー プロセスで実行されるコンパイル済みの C# 関数。 分離ワーカー プロセスは、LTS および 非 LTS バージョンの .NET および .NET Framework で実行されている C# 関数をサポートするために必要です。
  • インプロセス モデル: Functions ランタイムと同じプロセスで実行されるコンパイル済みの C# 関数。
  • C# スクリプト: Azure portal で C# 関数を作成するときに主に使用されます。

次の例は、出力バインドを使用してすべての接続済みクライアントにメッセージを送信する関数を示しています。 newMessage は、各クライアントで呼び出されるメソッドの名前です。

[Function(nameof(BroadcastToAll))]
[SignalROutput(HubName = "chat", ConnectionStringSetting = "SignalRConnection")]
public static SignalRMessageAction BroadcastToAll([HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequestData req)
{
    using var bodyReader = new StreamReader(req.Body);
    return new SignalRMessageAction("newMessage")
    {
        // broadcast to all the connected clients without specifying any connection, user or group.
        Arguments = new[] { bodyReader.ReadToEnd() },
    };
}

function.json ファイルのバインド データを次に示します。

function.json の例:

{
  "type": "signalR",
  "name": "signalROutput",
  "hubName": "hubName1",
  "connectionStringSetting": "<name of setting containing SignalR Service connection string>",
  "direction": "out"
}
const { app, output } = require('@azure/functions');

const signalR = output.generic({
    type: 'signalR',
    name: 'signalR',
    hubName: 'hub',
    connectionStringSetting: 'AzureSignalRConnectionString',
});

// You can use any other trigger type instead.
app.http('broadcast', {
    methods: ['GET'],
    authLevel: 'anonymous',
    extraOutputs: [signalR],
    handler: (request, context) => {
        context.extraOutputs.set(signalR, {
            "target": "newMessage",
            "arguments": [request.body]
        });
    }
});

PowerShell の完全な例は保留中です。

Python コードを次に示します。

def main(req: func.HttpRequest, signalROutput: func.Out[str]) -> func.HttpResponse:
    message = req.get_json()
    signalROutput.set(json.dumps({
        'target': 'newMessage',
        'arguments': [ message ]
    }))
@FunctionName("sendMessage")
@SignalROutput(name = "$return", HubName = "hubName1")
public SignalRMessage sendMessage(
        @HttpTrigger(
            name = "req",
            methods = { HttpMethod.POST },
            authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Object> req) {

    SignalRMessage message = new SignalRMessage();
    message.target = "newMessage";
    message.arguments.add(req.getBody());
    return message;
}

ユーザーに送信する

ユーザーに対して認証された接続だけにメッセージを送信するには、SignalR メッセージの user ID を設定します。

[Function(nameof(SendToUser))]
[SignalROutput(HubName = "chat", ConnectionStringSetting = "SignalRConnection")]
public static SignalRMessageAction SendToUser([HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequestData req)
{
    using var bodyReader = new StreamReader(req.Body);
    return new SignalRMessageAction("newMessage")
    {
        Arguments = new[] { bodyReader.ReadToEnd() },
        UserId = "userToSend",
    };
}

function.json ファイルのバインド データを次に示します。

function.json の例:

{
  "type": "signalR",
  "name": "signalROutput",
  "hubName": "hubName1",
  "connectionStringSetting": "<name of setting containing SignalR Service connection string>",
  "direction": "out"
}

PowerShell の完全な例は保留中です。

Python コードを次に示します。

def main(req: func.HttpRequest, signalROutput: func.Out[str]) -> func.HttpResponse:
    message = req.get_json()
    signalROutput.set(json.dumps({
        #message will only be sent to this user ID
        'userId': 'userId1',
        'target': 'newMessage',
        'arguments': [ message ]
    }))
@FunctionName("sendMessage")
@SignalROutput(name = "$return", HubName = "hubName1")
public SignalRMessage sendMessage(
        @HttpTrigger(
            name = "req",
            methods = { HttpMethod.POST },
            authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Object> req) {

    SignalRMessage message = new SignalRMessage();
    message.userId = "userId1";
    message.target = "newMessage";
    message.arguments.add(req.getBody());
    return message;
}
const { app, output } = require('@azure/functions');

const signalR = output.generic({
    type: 'signalR',
    name: 'signalR',
    hubName: 'hub',
    connectionStringSetting: 'AzureSignalRConnectionString',
});

app.http('sendToUser', {
    methods: ['GET'],
    authLevel: 'anonymous',
    extraOutputs: [signalR],
    handler: (request, context) => {
        context.extraOutputs.set(signalR, {
            "target": "newMessage",
            "arguments": [request.body],
            "userId": "userId1",
        });
    }
});

グループに送信する

グループに追加された接続だけにメッセージを送信するには、SignalR メッセージの group name を設定します。

[Function(nameof(SendToGroup))]
[SignalROutput(HubName = "chat", ConnectionStringSetting = "SignalRConnection")]
public static SignalRMessageAction SendToGroup([HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequestData req)
{
    using var bodyReader = new StreamReader(req.Body);
    return new SignalRMessageAction("newMessage")
    {
        Arguments = new[] { bodyReader.ReadToEnd() },
        GroupName = "groupToSend"
    };
}

function.json ファイルのバインド データを次に示します。

function.json の例:

{
  "type": "signalR",
  "name": "signalROutput",
  "hubName": "hubName1",
  "connectionStringSetting": "<name of setting containing SignalR Service connection string>",
  "direction": "out"
}
const { app, output } = require('@azure/functions');

const signalR = output.generic({
    type: 'signalR',
    name: 'signalR',
    hubName: 'hub',
    connectionStringSetting: 'AzureSignalRConnectionString',
});

app.http('sendToGroup', {
    methods: ['GET'],
    authLevel: 'anonymous',
    extraOutputs: [signalR],
    handler: (request, context) => {
        context.extraOutputs.set(signalR, {
            "target": "newMessage",
            "arguments": [request.body],
            "groupName": "myGroup",
        });
    }
});

PowerShell の完全な例は保留中です。

Python コードを次に示します。

def main(req: func.HttpRequest, signalROutput: func.Out[str]) -> func.HttpResponse:
    message = req.get_json()
    signalROutput.set(json.dumps({
        #message will only be sent to this group
        'groupName': 'myGroup',
        'target': 'newMessage',
        'arguments': [ message ]
    }))
@FunctionName("sendMessage")
@SignalROutput(name = "$return", HubName = "hubName1")
public SignalRMessage sendMessage(
        @HttpTrigger(
            name = "req",
            methods = { HttpMethod.POST },
            authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Object> req) {

    SignalRMessage message = new SignalRMessage();
    message.groupName = "myGroup";
    message.target = "newMessage";
    message.arguments.add(req.getBody());
    return message;
}

グループ管理

SignalR Service を使用すると、ユーザーまたは接続をグループに追加できます。 その後にメッセージをグループに送信できます。 SignalR 出力バインドを使ってグループを管理することができます。

メンバーを追加または削除する SignalRGroupActionType を指定します。 次の例では、ユーザーをグループから削除します。

[Function(nameof(RemoveFromGroup))]
[SignalROutput(HubName = "chat", ConnectionStringSetting = "SignalRConnection")]
public static SignalRGroupAction RemoveFromGroup([HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequestData req)
{
    return new SignalRGroupAction(SignalRGroupActionType.Remove)
    {
        GroupName = "group1",
        UserId = "user1"
    };
}

Note

ClaimsPrincipal を正しくバインドするためには、Azure Functions で認証設定を構成しておく必要があります。

function.json ファイルのバインド データを次に示します。

function.json の例:

{
  "type": "signalR",
  "name": "signalROutput",
  "hubName": "hubName1",
  "connectionStringSetting": "<name of setting containing SignalR Service connection string>",
  "direction": "out"
}
const { app, output } = require('@azure/functions');

const signalR = output.generic({
    type: 'signalR',
    name: 'signalR',
    hubName: 'hub',
    connectionStringSetting: 'AzureSignalRConnectionString',
});

// The following function adds a user to a group
app.http('addUserToGroup', {
    methods: ['POST'],
    authLevel: 'anonymous',
    extraOutputs: [signalR],
    handler: (request, context) => {
        context.extraOutputs.set(signalR, {
            "userId": req.query.userId,
            "groupName": "myGroup",
            "action": "add"
        });
    }
});

// The following function removes a user from a group
app.http('removeUserFromGroup', {
    methods: ['POST'],
    authLevel: 'anonymous',
    extraOutputs: [signalR],
    handler: (request, context) => {
        context.extraOutputs.set(signalR, {
            "userId": req.query.userId,
            "groupName": "myGroup",
            "action": "remove"
        });
    }
});

PowerShell の完全な例は保留中です。

次の例では、ユーザーをグループに追加します。

def main(req: func.HttpRequest, signalROutput: func.Out[str]) -> func.HttpResponse:
    signalROutput.set(json.dumps({
        'userId': 'userId1',
        'groupName': 'myGroup',
        'action': 'add'
    }))

次の例では、ユーザーをグループから削除します。

def main(req: func.HttpRequest, signalROutput: func.Out[str]) -> func.HttpResponse:
    signalROutput.set(json.dumps({
        'userId': 'userId1',
        'groupName': 'myGroup',
        'action': 'remove'
    }))

次の例では、ユーザーをグループに追加します。

@FunctionName("addToGroup")
@SignalROutput(name = "$return", HubName = "hubName1")
public SignalRGroupAction addToGroup(
        @HttpTrigger(
            name = "req",
            methods = { HttpMethod.POST },
            authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Object> req,
        @BindingName("userId") String userId) {

    SignalRGroupAction groupAction = new SignalRGroupAction();
    groupAction.action = "add";
    groupAction.userId = userId;
    groupAction.groupName = "myGroup";
    return action;
}

次の例では、ユーザーをグループから削除します。

@FunctionName("removeFromGroup")
@SignalROutput(name = "$return", HubName = "hubName1")
public SignalRGroupAction removeFromGroup(
        @HttpTrigger(
            name = "req",
            methods = { HttpMethod.POST },
            authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Object> req,
        @BindingName("userId") String userId) {

    SignalRGroupAction groupAction = new SignalRGroupAction();
    groupAction.action = "remove";
    groupAction.userId = userId;
    groupAction.groupName = "myGroup";
    return action;
}

属性

インプロセス分離ワーカー プロセスの C# ライブラリの両方で、属性を使用して関数を定義します。 C# スクリプトでは、代わりに function.json 構成ファイルを使います。

次の表では、SignalROutput 属性のプロパティについて説明します。

属性のプロパティ 説明
HubName この値は、接続情報が生成される SignalR ハブの名前に設定する必要があります。
ConnectionStringSetting SignalR Service 接続文字列が含まれているアプリ設定の名前。この既定値は AzureSignalRConnectionString です。

注釈

次の表では、SignalROutput 注釈でサポートされている設定について説明します。

設定 内容
name 接続情報オブジェクトの関数コードで使用される変数名。
hubName この値は、接続情報が生成される SignalR ハブの名前に設定する必要があります。
connectionStringSetting SignalR Service 接続文字列が含まれているアプリ設定の名前。この既定値は AzureSignalRConnectionString です。

構成

次の表は、function.json ファイルで設定したバインド構成のプロパティを説明しています。

function.json のプロパティ 説明
type signalR に設定する必要があります。
direction out に設定する必要があります。
name 接続情報オブジェクトの関数コードで使用される変数名。
hubName この値は、接続情報が生成される SignalR ハブの名前に設定する必要があります。
connectionStringSetting SignalR Service 接続文字列が含まれているアプリ設定の名前。この既定値は AzureSignalRConnectionString です。

ローカルで開発する場合は、Values コレクション内の local.settings.json ファイルにアプリケーション設定を追加します。

次のステップ