共用方式為


Azure Functions 的 Azure Web PubSub 輸入系結

我們的延伸模組提供兩個以不同需求為目標的輸入繫結。

  • WebPubSubConnection

    若要讓用戶端連線到 Azure Web PubSub 服務,它必須知道服務端點 URL 和有效的存取權杖。 WebPubSubConnection 輸入繫結會產生必要的資訊,因此用戶端本身不需要處理這個權杖產生。 令牌有時間限制,而且可以驗證連線的特定使用者。 因此,請勿快取令牌或在客戶端之間共用令牌。 搭配此輸入繫結使用的 HTTP 觸發程序可以供用戶端用來擷取連線資訊。

  • WebPubSubContext

    使用靜態網頁應用程式時, HttpTrigger 是唯一支援的觸發條件。 在 Web PubSub 情境中, WebPubSubContext 輸入綁定幫助使用者在 Web PubSub 協定下反序列化來自服務的上游 HTTP 請求。 因此,與 WebPubSubTrigger 比較,客戶可以取得類似的結果,以便輕鬆地在函式中處理。 搭配 HttpTrigger 使用時,客戶必須相應地在事件處理常式中設定 HttpTrigger 公開 URL。

WebPubSubConnection

範例

下列範例示範使用輸入系結取得 Web PubSub 連線資訊的 HTTP 觸發程式函式,並透過 HTTP 傳回它。 在下列範例中, UserId 會透過用戶端要求查詢部分傳入 ,例如 ?userid={User-A}

[Function("WebPubSubConnectionInputBinding")]
public static HttpResponseData Run([HttpTrigger(AuthorizationLevel.Anonymous)] HttpRequestData req,
[WebPubSubConnectionInput(Hub = "<hub>", , UserId = "{query.userid}", Connection = "<web_pubsub_connection_name>")] WebPubSubConnection connectionInfo)
{
    var response = req.CreateResponse(HttpStatusCode.OK);
    response.WriteAsJsonAsync(connectionInfo);
    return response;
}
const { app, input } = require('@azure/functions');

const connection = input.generic({
    type: 'webPubSubConnection',
    name: 'connection',
    userId: '{query.userId}',
    hub: '<hub>'
});

app.http('negotiate', {
    methods: ['GET', 'POST'],
    authLevel: 'anonymous',
    extraInputs: [connection],
    handler: async (request, context) => {
        return { body: JSON.stringify(context.extraInputs.get('connection')) };
    },
});

建立資料夾交涉並更新交涉/function.json,並複製下列 JSON 程序代碼。

{
  "scriptFile": "__init__.py",
  "bindings": [
    {
      "authLevel": "anonymous",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req"
    },
    {
      "type": "http",
      "direction": "out",
      "name": "$return"
    },
    {
      "type": "webPubSubConnection",
      "name": "connection",
      "userId": "{query.userid}",
      "hub": "<hub>",
      "direction": "in"
    }
  ]
}

negotiate/init定義函式.py

import logging

import azure.functions as func

def main(req: func.HttpRequest, connection) -> func.HttpResponse:
    return func.HttpResponse(connection)

注意

此語言的完整範例擱置中

注意

目前尚不支援 Java 的 Web PubSub 擴充功能。

取得已驗證的使用者標識碼

如果函式是由已驗證的用戶端觸發,您可以將使用者識別碼宣告新增至產生的權杖。 您可以使用 [App Service 驗證],輕鬆地將驗證新增至函數應用程式。

App Service 驗證會設定名為 x-ms-client-principal-idx-ms-client-principal-name 的 HTTP 標頭,這些標頭分別包含已驗證使用者的用戶端主體識別碼和名稱。

您可以使用系結表示式,將系結的 屬性設定 UserId 為來自任一標頭的值: {headers.x-ms-client-principal-id}{headers.x-ms-client-principal-name}

[Function("WebPubSubConnectionInputBinding")]
public static HttpResponseData Run([HttpTrigger(AuthorizationLevel.Anonymous)] HttpRequestData req,
[WebPubSubConnectionInput(Hub = "<hub>", , UserId = "{headers.x-ms-client-principal-id}", Connection = "<web_pubsub_connection_name>")] WebPubSubConnection connectionInfo)
{
    var response = req.CreateResponse(HttpStatusCode.OK);
    response.WriteAsJsonAsync(connectionInfo);
    return response;
}
const { app, input } = require('@azure/functions');

const connection = input.generic({
    type: 'webPubSubConnection',
    name: 'connection',
    userId: '{headers.x-ms-client-principal-id}',
    hub: '<hub>'
});

app.http('negotiate', {
    methods: ['GET', 'POST'],
    authLevel: 'anonymous',
    extraInputs: [connection],
    handler: async (request, context) => {
        return { body: JSON.stringify(context.extraInputs.get('connection')) };
    },
});

建立資料夾交涉並更新交涉/function.json,並複製下列 JSON 程序代碼。

{
  "scriptFile": "__init__.py",
  "bindings": [
    {
      "authLevel": "anonymous",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req"
    },
    {
      "type": "http",
      "direction": "out",
      "name": "$return"
    },
    {
      "type": "webPubSubConnection",
      "name": "connection",
      "userId": "{headers.x-ms-client-principal-id}",
      "hub": "<hub>",
      "direction": "in"
    }
  ]
}

negotiate/init定義函式.py

import logging

import azure.functions as func

def main(req: func.HttpRequest, connection) -> func.HttpResponse:
    return func.HttpResponse(connection)

注意

此語言的完整範例擱置中

注意

目前尚不支援 Java 的 Web PubSub 擴充功能。

組態

下表說明您在 function.json 檔案中設定的繫結設定屬性內容和 WebPubSubConnection 屬性。

function.json 屬性 屬性內容 描述
類型 n/a 必須設定為 webPubSubConnection
方向 n/a 必須設定為 in
名字 n/a 函式程式碼中用於輸入連線繫結物件的變數名稱。
中樞 中樞 必要 - 針對要觸發的函式,此值必須設為其 Web PubSub 中樞的名稱。 我們支援將屬性中的該值設定為較高的優先順序,或者可以在應用程式設定中將其設定為全域值。
userId UserId 選擇性:要在存取金鑰權杖中設定的使用者識別碼宣告值。
clientProtocol ClientProtocol 選擇性 - 用戶端通訊協議類型。 有效值包括 defaultmqtt
針對 MQTT 用戶端,您必須將它設定為 mqtt
對於其他用戶端,您可以省略 屬性或將它設定為 default
連接 連線 必要 - 包含 Web PubSub 服務連接字串的應用程式設定名稱 (預設值為「WebPubSubConnectionString」)。

使用方式

WebPubSubConnection 提供下列屬性。

繫結名稱 繫結類型 描述
基礎URI (BaseUri) URI Web PubSub 用戶端連線 URI。
URI URI Web PubSub 連線的絕對 URI,其中包含根據要求所產生的 AccessToken
AccessToken 字串 根據要求 UserId 和服務資訊所產生的 AccessToken

WebPubSubConnection 提供下列屬性。

繫結名稱 描述
baseUrl 的 Web PubSub 用戶端連線 URI。
URL Web PubSub 連線的絕對 URI,其中包含根據要求所產生的 AccessToken
accessToken 根據要求 UserId 和服務資訊所產生的 AccessToken

注意

目前尚不支援 Java 的 Web PubSub 擴充功能。

所產生令牌的更多自定義

受限於係結參數類型不支援傳遞清單或陣列的方式,並非所有參數伺服器 SDK 都完全支援, WebPubSubConnection 特別是 roles,也包含 groupsexpiresAfter

當客戶需要在函式中新增角色或延遲建置存取令牌時,建議您使用 適用於 C# 的伺服器 SDK。

[Function("WebPubSubConnectionCustomRoles")]
public static HttpResponseData Run([HttpTrigger(AuthorizationLevel.Anonymous)] HttpRequestData req)
{
    var serviceClient = new WebPubSubServiceClient(new Uri(endpoint), "<hub>", "<web-pubsub-connection-string>");
    var userId = req.Query["userid"].FirstOrDefault();
    // your method to get custom roles.
    var roles = GetRoles(userId);
    var url = await serviceClient.GetClientAccessUriAsync(TimeSpan.FromMinutes(5), userId, roles);
    var response = req.CreateResponse(HttpStatusCode.OK);
    response.WriteString(url.ToString());
    return response;
}

當客戶需要在函式中新增角色或延遲建置存取令牌時,建議您使用 適用於 JavaScript 的伺服器 SDK。

const { app } = require('@azure/functions');
const { WebPubSubServiceClient } = require('@azure/web-pubsub');
app.http('negotiate', {
    methods: ['GET', 'POST'],
    authLevel: 'anonymous',
    handler: async (request, context) => {
        const serviceClient = new WebPubSubServiceClient(process.env.WebPubSubConnectionString, "<hub>");
        let token = await serviceClient.getAuthenticationToken({ userId: req.query.userid, roles: ["webpubsub.joinLeaveGroup", "webpubsub.sendToGroup"] });
        return { body: token.url };
    },
});

注意

此語言的完整範例擱置中

注意

目前尚不支援 Java 的 Web PubSub 擴充功能。

WebPubSubContext

範例

// validate method when upstream set as http://<func-host>/api/{event}
[Function("validate")]
public static HttpResponseData Validate(
    [HttpTrigger(AuthorizationLevel.Anonymous, "options")] HttpRequestData req,
    [WebPubSubContextInput] WebPubSubContext wpsReq)
{
    return BuildHttpResponseData(req, wpsReq.Response);
}

// Respond AbuseProtection to put header correctly.
private static HttpResponseData BuildHttpResponseData(HttpRequestData request, SimpleResponse wpsResponse)
{
    var response = request.CreateResponse();
    response.StatusCode = (HttpStatusCode)wpsResponse.Status;
    response.Body = response.Body;
    foreach (var header in wpsResponse.Headers)
    {
        response.Headers.Add(header.Key, header.Value);
    }
    return response;
}
const { app, input } = require('@azure/functions');

const wpsContext = input.generic({
    type: 'webPubSubContext',
    name: 'wpsContext'
});

app.http('connect', {
    methods: ['GET', 'POST'],
    authLevel: 'anonymous',
    extraInputs: [wpsContext],
    handler: async (request, context) => {
        var wpsRequest = context.extraInputs.get('wpsContext');

        return { "userId": wpsRequest.request.connectionContext.userId };
    }
});

注意

此語言的完整範例擱置中

注意

目前尚不支援 Java 的 Web PubSub 擴充功能。

組態

下表說明您在 function.json 檔案中設定的繫結設定屬性內容和 WebPubSubContext 屬性。

function.json 屬性 屬性內容 描述
類型 n/a 必須設定為 webPubSubContext
方向 n/a 必須設定為 in
名字 n/a 函式程式碼中用於輸入 Web PubSub 要求的變數名稱。
連接 連線 選擇性 - 指定上游 Azure Web PubSub 服務的應用程式設定名稱或設定集合名稱。 此值用於濫用保護和簽章驗證。 此值預設為使用「WebPubSubConnectionString」進行自動解析。 這 null 表示不需要驗證,且一律會成功。

重要

為了獲得最佳安全性,函式應用程式應該在連線到 Web PubSub 服務時使用受控識別,而不是使用包含共用秘密密鑰的連接字串。 如需詳細資訊,請參閱 使用 Microsoft Entra ID 授權受控識別要求。

使用方式

WebPubSubContext 提供下列屬性。

繫結名稱 繫結類型 描述 屬性
要求 WebPubSubEventRequest 請向用戶端要求,請參閱下表以取得詳細數據。 要求標頭的 WebPubSubConnectionContext 與其他從要求本文還原序列化的屬性可描述要求,例如,適用於 ReasonDisconnectedEventRequest
回覆 HttpResponseMessage 延伸模組主要會針對 AbuseProtection 和錯誤案例建置回應。 -
錯誤消息 字串 描述處理上游要求時的錯誤詳細資料。 -
hasError 布爾 (bool) 旗標,指出它是否為有效的 Web PubSub 上游要求。 -
isPreflight 布爾 (bool) 旗標,指出它是否為 AbuseProtection 的預檢要求。 -

針對 WebPubSubEventRequest,它會還原序列化為不同類別,以提供有關要求情節的不同資訊。 若為 PreflightRequest 或無效案例,使用者可以檢查旗標 IsPreflightHasError 以進行了解。 建議您直接傳回系統組建回應 WebPubSubContext.Response ,或者客戶可以視需要記錄錯誤。 在不同的案例中,客戶可以讀取要求屬性,如下所示。

衍生類別 描述 屬性
PreflightRequest 用於 AbuseProtection (當 IsPreflighttrue 時) -
ConnectEventRequest 用於系統 Connect 事件類型 Claims、Query、Subprotocols、ClientCertificates
ConnectedEventRequest 用於系統 Connected 事件類型 -
UserEventRequest 用於使用者事件類型 Data、DataType
DisconnectedEventRequest 用於系統 Disconnected 事件類型 原因

注意

WebPubSubContext雖然 是輸入系結,但相較於 HttpTrigger提供WebPubSubTrigger類似的要求還原串行化方式,但有一定限制,亦即不支持合併后的連線狀態。 服務端仍會遵守傳回回應,但使用者需要自行建置回應。 如果使用者必須設定事件回應,您應該傳回包含 HttpResponseMessageConnectEventResponse,或者使用者事件的訊息作為回應本文,並將具有索引鍵 ce-connectionstate 的連線狀態,放在回應標頭中。