Partilhar via


Ligação de saída do Serviço SignalR para o Azure Functions

Use a associação de saída do SignalR para enviar uma ou mais mensagens usando o Serviço Azure SignalR. Você pode transmitir uma mensagem para:

  • Todos os clientes conectados
  • Clientes conectados em um grupo especificado
  • Clientes conectados autenticados para um usuário específico

A associação de saída também permite gerenciar grupos, como adicionar um cliente ou usuário a um grupo, remover um cliente ou usuário de um grupo.

Para obter informações sobre detalhes de instalação e configuração, consulte a visão geral.

Exemplo

Transmissão para todos os clientes

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 que envia uma mensagem usando a associação de saída para todos os clientes conectados. O newMessage é o nome do método a ser invocado em cada cliente.

[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() },
    };
}

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

Exemplo 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]
        });
    }
});

Exemplos completos do PowerShell estão pendentes.

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

Enviar a um utilizador

Você pode enviar uma mensagem somente para conexões que foram autenticadas para um usuário definindo o ID do usuário na mensagem do SignalR.

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

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

Exemplo function.json:

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

Exemplos completos do PowerShell estão pendentes.

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

Enviar para um grupo

Você pode enviar uma mensagem somente para conexões que foram adicionadas a um grupo definindo o nome do grupo na mensagem SignalR.

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

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

Exemplo 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",
        });
    }
});

Exemplos completos do PowerShell estão pendentes.

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

Gestão de grupos

O Serviço SignalR permite que usuários ou conexões sejam adicionados a grupos. As mensagens podem então ser enviadas para um grupo. Você pode usar a SignalR associação de saída para gerenciar grupos.

Especifique SignalRGroupActionType para adicionar ou remover um membro. O exemplo a seguir remove um usuário de um grupo.

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

Nota

Para obter o ClaimsPrincipal limite correto, você deve ter configurado as configurações de autenticação no Azure Functions.

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

Exemplo 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"
        });
    }
});

Exemplos completos do PowerShell estão pendentes.

O exemplo a seguir adiciona um usuário a um grupo.

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

O exemplo a seguir remove um usuário de um grupo.

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

O exemplo a seguir adiciona um usuário a um grupo.

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

O exemplo a seguir remove um usuário de um grupo.

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

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 SignalROutput atributo.

Propriedade Attribute Description
Nome do Hub; Esse valor deve ser definido como o nome do hub SignalR para o qual as informações de conexão são geradas.
ConnectionStringSetting O nome da configuração do aplicativo ou da coleção de configurações que contém a cadeia de conexão do Serviço SignalR, cujo padrão é AzureSignalRConnectionString.

Anotações

A tabela a seguir explica as configurações suportadas para a SignalROutput 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 Esse valor deve ser definido como o nome do hub SignalR para o qual as informações de conexão são geradas.
connectionStringSetting O nome da configuração do aplicativo ou da coleção de configurações que contém a cadeia de conexão do Serviço SignalR, cujo padrão é AzureSignalRConnectionString.

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 signalR.
direção Deve ser definido como out.
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 Esse valor deve ser definido como o nome do hub SignalR para o qual as informações de conexão são geradas.
connectionStringSetting O nome da configuração do aplicativo ou da coleção de configurações que contém a cadeia de conexão do Serviço SignalR, cujo padrão é AzureSignalRConnectionString.

Quando estiver desenvolvendo localmente, adicione as configurações do aplicativo no arquivo local.settings.json na Values coleção.

Utilização

Para uma segurança ideal, seu aplicativo de função deve usar identidades gerenciadas ao se conectar ao serviço Azure SignalR em vez de usar uma cadeia de conexão, que contém uma chave de segredo compartilhado. Para obter mais informações, consulte Autorizar solicitações para recursos do Serviço Azure SignalR com identidades gerenciadas do Microsoft Entra.

Próximos passos