次の方法で共有


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

クライアントが Azure SignalR Service に接続するには、そのクライアントに、サービス エンドポイント URL と有効なアクセス トークンが必要です。 サービスへの接続に使用される SignalR Service エンドポイント URL と有効なトークンは、SignalRConnectionInfo 入力バインドによって生成されます。 トークンは時間制限があり、接続に対して特定のユーザーを認証するために使用できます。 そのため、トークンをキャッシュしたり、クライアント間で共有したりしないでください。 通常、クライアントが接続情報を取得するには、SignalRConnectionInfo と HTTP トリガーを使用します。

このバインドを使用して SignalR クライアント SDK と互換性のある "negotiate" 関数を作成する方法の詳細については、「Azure SignalR Service を使用した Azure Functions の開発と構成」を参照してください。 セットアップと構成の詳細については、概要に関するページをご覧ください。

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

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

次の例は、入力バインドを使用して SignalR 接続情報を取得し、HTTP 経由でそれを返す C# 関数を示しています。

[Function(nameof(Negotiate))]
public static string Negotiate([HttpTrigger(AuthorizationLevel.Anonymous)] HttpRequestData req,
    [SignalRConnectionInfoInput(HubName = "serverless")] string connectionInfo)
{
    // The serialization of the connection info object is done by the framework. It should be camel case. The SignalR client respects the camel case response only.
    return connectionInfo;
}

次の例は、function.json ファイル内の SignalR 接続情報入力バインディングと、そのバインディングを使用して接続情報を返す関数を示しています。

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

{
    "type": "signalRConnectionInfo",
    "name": "connectionInfo",
    "hubName": "hubName1",
    "connectionStringSetting": "<name of setting containing SignalR Service connection string>",
    "direction": "in"
}

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

const { app, input } = require('@azure/functions');

const inputSignalR = input.generic({
    type: 'signalRConnectionInfo',
    name: 'connectionInfo',
    hubName: 'hubName1',
    connectionStringSetting: 'AzureSignalRConnectionString',
});

app.post('negotiate', {
    authLevel: 'function',
    handler: (request, context) => {
        return { body: JSON.stringify(context.extraInputs.get(inputSignalR)) }
    },
    route: 'negotiate',
    extraInputs: [inputSignalR],
});

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

次の例は、function.json ファイルの SignalR 接続情報入力バインドと、そのバインドを使用して接続情報を返す Python 関数を示しています。

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

def main(req: func.HttpRequest, connectionInfoJson: str) -> func.HttpResponse:
    return func.HttpResponse(
        connectionInfoJson,
        status_code=200,
        headers={
            'Content-type': 'application/json'
        }
    )

次の例は、入力バインドを使用して SignalR 接続情報を取得し、HTTP 経由でそれを返す Java 関数を示しています。

@FunctionName("negotiate")
public SignalRConnectionInfo negotiate(
        @HttpTrigger(
            name = "req",
            methods = { HttpMethod.POST },
            authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> req,
        @SignalRConnectionInfoInput(
            name = "connectionInfo",
            HubName = "hubName1") SignalRConnectionInfo connectionInfo) {
    return connectionInfo;
}

使用方法

認証済みトークン

認証済みクライアントによって関数がトリガーされている場合は、ユーザー ID 要求を生成済みトークンに追加できます。 App Service 認証を使用すると、認証を関数アプリに簡単に追加することができます。

App Service 認証では、それぞれ、認証されたユーザーのクライアント プリンシパルの ID と名前が含まれている x-ms-client-principal-idx-ms-client-principal-name という名前の HTTP ヘッダーが設定されます。

バインドの UserId プロパティをいずれかのヘッダーの値に設定するには、バインド式として {headers.x-ms-client-principal-id} または {headers.x-ms-client-principal-name} を使用します。

[Function("Negotiate")]
public static string Negotiate([HttpTrigger(AuthorizationLevel.Anonymous)] HttpRequestData req,
    [SignalRConnectionInfoInput(HubName = "hubName1", UserId = "{headers.x-ms-client-principal-id}")] string connectionInfo)
{
    // The serialization of the connection info object is done by the framework. It should be camel case. The SignalR client respects the camel case response only.
    return connectionInfo;
}
@FunctionName("negotiate")
public SignalRConnectionInfo negotiate(
        @HttpTrigger(
            name = "req",
            methods = { HttpMethod.POST, HttpMethod.GET },
            authLevel = AuthorizationLevel.ANONYMOUS)
            HttpRequestMessage<Optional<String>> req,
        @SignalRConnectionInfoInput(name = "connectionInfo", hubName = "hubName1", userId = "{headers.x-ms-signalr-userid}") SignalRConnectionInfo connectionInfo) {
    return connectionInfo;
}

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

{
    "type": "signalRConnectionInfo",
    "name": "connectionInfo",
    "hubName": "hubName1",
    "userId": "{headers.x-ms-client-principal-id}",
    "connectionStringSetting": "<name of setting containing SignalR Service connection string>",
    "direction": "in"
}

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

const { app, input } = require('@azure/functions');

const inputSignalR = input.generic({
    type: 'signalRConnectionInfo',
    name: 'connectionInfo',
    hubName: 'hubName1',
    connectionStringSetting: 'AzureSignalRConnectionString',
    userId: '{headers.x-ms-client-principal-id}',
});

app.post('negotiate', {
    authLevel: 'function',
    handler: (request, context) => {
        return { body: JSON.stringify(context.extraInputs.get(inputSignalR)) }
    },
    route: 'negotiate',
    extraInputs: [inputSignalR],
});

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

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

def main(req: func.HttpRequest, connectionInfo: str) -> func.HttpResponse:
    # connectionInfo contains an access key token with a name identifier
    # claim set to the authenticated user
    return func.HttpResponse(
        connectionInfo,
        status_code=200,
        headers={
            'Content-type': 'application/json'
        }
    )
@FunctionName("negotiate")
public SignalRConnectionInfo negotiate(
        @HttpTrigger(
            name = "req",
            methods = { HttpMethod.POST },
            authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> req,
        @SignalRConnectionInfoInput(
            name = "connectionInfo",
            HubName = "hubName1",
            userId = "{headers.x-ms-client-principal-id}") SignalRConnectionInfo connectionInfo) {
    return connectionInfo;
}

属性

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

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

属性のプロパティ 説明
HubName 必須。 ハブ名。
ConnectionStringSetting SignalR Service 接続文字列が含まれているアプリ設定の名前。この既定値は AzureSignalRConnectionString です。
UserId 省略可能。 SignalR 接続のユーザー識別子。 バインド式を使用して、値を HTTP 要求ヘッダーまたはクエリにバインドできます。
IdToken 省略可能。 ユーザー要求にクレームが追加される JWT トークン。 ClaimTypeList と共に使用する必要があります。 バインド式を使用して、値を HTTP 要求ヘッダーまたはクエリにバインドできます。
ClaimTypeList 省略可能。 IdToken の要求をフィルター処理する要求の種類の一覧。

注釈

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

設定 内容
name 接続情報オブジェクトの関数コードで使用される変数名。
hubName 必須。 ハブ名。
connectionStringSetting SignalR Service 接続文字列が含まれているアプリ設定の名前。この既定値は AzureSignalRConnectionString です。
userId 省略可能。 SignalR 接続のユーザー識別子。 バインド式を使用して、値を HTTP 要求ヘッダーまたはクエリにバインドできます。
idToken 省略可能。 ユーザー要求にクレームが追加される JWT トークン。 claimTypeList と共に使用する必要があります。 バインド式を使用して、値を HTTP 要求ヘッダーまたはクエリにバインドできます。
claimTypeList 省略可能。 idToken の要求をフィルター処理する要求の種類の一覧。

注釈

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

設定 内容
name 接続情報オブジェクトの関数コードで使用される変数名。
hubName 必須。 ハブ名。
connectionStringSetting SignalR Service 接続文字列が含まれているアプリ設定の名前。この既定値は AzureSignalRConnectionString です。
userId 省略可能。 SignalR 接続のユーザー識別子。 バインド式を使用して、値を HTTP 要求ヘッダーまたはクエリにバインドできます。
idToken 省略可能。 ユーザー要求にクレームが追加される JWT トークン。 claimTypeList と共に使用する必要があります。 バインド式を使用して、値を HTTP 要求ヘッダーまたはクエリにバインドできます。
claimTypeList 省略可能。 idToken の要求をフィルター処理する要求の種類の一覧。

構成

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

function.json のプロパティ 説明
type signalRConnectionInfo に設定する必要があります。
direction in に設定する必要があります。
hubName 必須。 ハブ名。
connectionStringSetting SignalR Service 接続文字列が含まれているアプリ設定の名前。この既定値は AzureSignalRConnectionString です。
userId 省略可能。 SignalR 接続のユーザー識別子。 バインド式を使用して、値を HTTP 要求ヘッダーまたはクエリにバインドできます。
idToken 省略可能。 ユーザー要求にクレームが追加される JWT トークン。 claimTypeList と共に使用する必要があります。 バインド式を使用して、値を HTTP 要求ヘッダーまたはクエリにバインドできます。
claimTypeList 省略可能。 idToken の要求をフィルター処理する要求の種類の一覧。

HTTP トリガーのバインド式

これは、SignalR 入力バインディングの一部の属性の値が HTTP 要求で取得される一般的なシナリオです。 そのため、バインド式を介して HTTP 要求の値を SignalR 入力バインド属性にバインドする方法を示します。

HTTP メタデータの種類 バインド式の形式 説明
HTTP 要求クエリ {query.QUERY_PARAMETER_NAME} 対応するクエリ パラメーターの値を属性にバインドする {query.userName}
HTTP 要求ヘッダー {headers.HEADER_NAME} ヘッダーの値を属性にバインドする {headers.token}

次のステップ