Vinculação de entrada do Serviço SignalR para o Azure Functions

Antes que um cliente possa se conectar ao Serviço Azure SignalR, ele deve recuperar a URL do ponto de extremidade do serviço e um token de acesso válido. A ligação de entrada SignalRConnectionInfo produz a URL do ponto de extremidade do Serviço SignalR e um token válido que são usados para se conectar ao serviço. O token é limitado no tempo e pode ser usado para autenticar um usuário específico em uma conexão. Portanto, você não deve armazenar o token em cache ou compartilhá-lo entre clientes. Normalmente, você usa SignalRConnectionInfo com gatilho HTTP para que os clientes recuperem as informações de conexão.

Para obter mais informações sobre como usar essa associação para criar uma função de "negociação" compatível com um SDK de cliente SignalR, consulte Desenvolvimento e configuração do Azure Functions com o Serviço SignalR do Azure. Para obter informações sobre detalhes de instalação e configuração, consulte a visão geral.

Exemplo

Uma função C# pode ser criada usando um dos seguintes modos C#:

  • Modelo de trabalho isolado: função C# compilada que é executada em um processo de trabalho isolado do tempo de execução. O processo de trabalho isolado é necessário para suportar funções C# em execução nas versões LTS e não-LTS .NET e .NET Framework.
  • Modelo em processo: função C# compilada que é executada no mesmo processo que o tempo de execução do Functions.
  • Script C#: usado principalmente quando você cria funções C# no portal do Azure.

Importante

O suporte para o modelo em processo terminará em 10 de novembro de 2026. É altamente recomendável que você migre seus aplicativos para o modelo de trabalho isolado para obter suporte total.

O exemplo a seguir mostra uma função C# que adquire informações de conexão SignalR usando a associação de entrada e as retorna por HTTP.

[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;
}

O exemplo a seguir mostra uma ligação de entrada de informações de conexão SignalR em um arquivo function.json e uma função que usa a associação para retornar as informações de conexão.

Aqui estão os dados de vinculação para o exemplo no arquivo function.json :

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

Aqui está o código 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],
});

Exemplos completos do PowerShell estão pendentes.

O exemplo a seguir mostra uma ligação de entrada de informações de conexão SignalR em um arquivo function.json e uma função Python que usa a associação para retornar as informações de conexão.

Aqui está o código Python:

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

O exemplo a seguir mostra uma função Java que adquire informações de conexão SignalR usando a ligação de entrada e as retorna por HTTP.

@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;
}

Utilização

Tokens autenticados

Quando um cliente autenticado aciona a função, você pode adicionar uma declaração de ID de usuário ao token gerado. Você pode facilmente adicionar autenticação a um aplicativo de função usando a Autenticação do Serviço de Aplicativo.

A autenticação do Serviço de Aplicativo define cabeçalhos HTTP nomeados x-ms-client-principal-id e x-ms-client-principal-name que contêm o ID e o nome da entidade do cliente do usuário autenticado, respectivamente.

Você pode definir a UserId propriedade da associação para o valor de qualquer cabeçalho usando uma expressão de ligação: {headers.x-ms-client-principal-id} ou {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;
}

Aqui estão os dados de vinculação no arquivo 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"
}

Aqui está o código 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],
});

Exemplos completos do PowerShell estão pendentes.

Aqui está o código 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;
}

Atributos

As bibliotecas C# do processo de trabalho em processo e isoladas usam o atributo para definir a função. Em vez disso, o script C# usa um arquivo de configuração function.json.

A tabela a seguir explica as propriedades do SignalRConnectionInfoInput atributo:

Propriedade Attribute Description
Nome do Hub; Obrigatório. O nome do hub.
ConnectionStringSetting O nome da configuração do aplicativo que contém a cadeia de conexão do Serviço SignalR, cujo padrão é AzureSignalRConnectionString.
UserId Opcional. O identificador de usuário de uma conexão SignalR. Você pode usar uma expressão de associação para vincular o valor a um cabeçalho de solicitação HTTP ou consulta.
IdToken Opcional. Um token JWT cujas declarações serão adicionadas às declarações do usuário. Ele deve ser usado em conjunto com ClaimTypeList. Você pode usar uma expressão de associação para vincular o valor a um cabeçalho de solicitação HTTP ou consulta.
ClaimTypeList Opcional. Uma lista de tipos de declaração, que filtram as declarações em IdToken .

Anotações

A tabela a seguir explica as configurações suportadas para a SignalRConnectionInfoInput anotação.

Definição Description
Designação Nome da variável usado no código de função para o objeto de informações de conexão.
Nome do hub Obrigatório. O nome do hub.
connectionStringSetting O nome da configuração do aplicativo que contém a cadeia de conexão do Serviço SignalR, cujo padrão é AzureSignalRConnectionString.
userId Opcional. O identificador de usuário de uma conexão SignalR. Você pode usar uma expressão de associação para vincular o valor a um cabeçalho de solicitação HTTP ou consulta.
idToken Opcional. Um token JWT cujas declarações serão adicionadas às declarações do usuário. Ele deve ser usado em conjunto com claimTypeList. Você pode usar uma expressão de associação para vincular o valor a um cabeçalho de solicitação HTTP ou consulta.
claimTypeList Opcional. Uma lista de tipos de declaração, que filtram as declarações em idToken .

Anotações

A tabela a seguir explica as configurações suportadas para a SignalRConnectionInfoInput anotação.

Definição Description
Designação Nome da variável usado no código de função para o objeto de informações de conexão.
Nome do hub Obrigatório. O nome do hub.
connectionStringSetting O nome da configuração do aplicativo que contém a cadeia de conexão do Serviço SignalR, cujo padrão é AzureSignalRConnectionString.
userId Opcional. O identificador de usuário de uma conexão SignalR. Você pode usar uma expressão de associação para vincular o valor a um cabeçalho de solicitação HTTP ou consulta.
idToken Opcional. Um token JWT cujas declarações serão adicionadas às declarações do usuário. Ele deve ser usado em conjunto com claimTypeList. Você pode usar uma expressão de associação para vincular o valor a um cabeçalho de solicitação HTTP ou consulta.
claimTypeList Opcional. Uma lista de tipos de declaração, que filtram as declarações em idToken .

Configuração

A tabela a seguir explica as propriedades de configuração de associação definidas no arquivo function.json .

function.json propriedade Description
type Deve ser definido como signalRConnectionInfo.
direção Deve ser definido como in.
Nome do hub Obrigatório. O nome do hub.
connectionStringSetting O nome da configuração do aplicativo que contém a cadeia de conexão do Serviço SignalR, cujo padrão é AzureSignalRConnectionString.
userId Opcional. O identificador de usuário de uma conexão SignalR. Você pode usar uma expressão de associação para vincular o valor a um cabeçalho de solicitação HTTP ou consulta.
idToken Opcional. Um token JWT cujas declarações serão adicionadas às declarações do usuário. Ele deve ser usado em conjunto com claimTypeList. Você pode usar uma expressão de associação para vincular o valor a um cabeçalho de solicitação HTTP ou consulta.
claimTypeList Opcional. Uma lista de tipos de declaração, que filtram as declarações em idToken .

Expressões de vinculação para gatilho HTTP

É um cenário comum que os valores de alguns atributos da ligação de entrada SignalR vêm de solicitações HTTP. Portanto, mostramos como vincular valores de solicitações HTTP a atributos de vinculação de entrada do SignalR por meio da expressão de vinculação.

Tipo de metadados HTTP Formato de expressão de vinculação Description Exemplo
Consulta de solicitação HTTP {query.QUERY_PARAMETER_NAME} Vincula o valor do parâmetro de consulta correspondente a um atributo {query.userName}
Cabeçalho da solicitação HTTP {headers.HEADER_NAME} Vincula o valor de um cabeçalho a um atributo {headers.token}

Próximos passos