Usar o SDK de Gerenciamento do Azure SignalR
O SDK de Gerenciamento do Azure SignalR ajuda você a gerenciar clientes do SignalR por meio do Serviço do Azure SignalR diretamente, como mensagens de transmissão. Portanto, esse SDK pode ser mas não é limitado a ser usado em ambientes sem servidor. Você pode usar esse SDK para gerenciar clientes do SignalR conectados ao serviço do Azure SignalR em qualquer ambiente, como em um aplicativo de console, em uma função do Azure ou em um servidor Web.
Observação
Para ver os guias do SDK versão 1.9.x e anteriores, acesse o SDK de Gerenciamento de Serviços do Azure SignalR (Herdado). Talvez você também queira ler as Diretrizes de migração.
Importante
As cadeias de conexão brutas aparecem neste artigo somente para fins de demonstração.
Uma cadeia de conexão inclui as informações de autorização necessárias para que o seu aplicativo acesse o serviço Azure Web PubSub. A chave de acesso dentro da cadeia de conexão é semelhante a uma senha raiz para o serviço. Em ambientes de produção, sempre proteja suas chaves de acesso. Use o Azure Key Vault para gerenciar e girar suas chaves com segurança e proteger sua cadeia de conexão usando o Microsoft Entra ID e autorizar o acesso com o Microsoft Entra ID.
Evite distribuir chaves de acesso para outros usuários, fazer hard-coding com elas ou salvá-las em qualquer lugar em texto sem formatação que seja acessível a outras pessoas. Gire suas chaves se você acredita que elas podem ter sido comprometidas.
Recursos
Recurso | Transitório | Persistente |
---|---|---|
Broadcast | ✔️ | ✔️ |
Difusão, exceto alguns clientes | ✔️ | ✔️ |
Enviar para um cliente | ✔️ | ✔️ |
Enviar para clientes | ✔️ | ✔️ |
Enviar para um usuário | ✔️ | ✔️ |
Enviar para usuários | ✔️ | ✔️ |
Enviar para um grupo | ✔️ | ✔️ |
Enviar para grupos | ✔️ | ✔️ |
Enviar para um grupo, exceto alguns clientes | ✔️ | ✔️ |
Para adicionar um usuário a um grupo | ✔️ | ✔️ |
Para remover um usuário de um grupo | ✔️ | ✔️ |
Verificar se um usuário em um grupo | ✔️ | ✔️ |
Suporte a várias instâncias de serviço do SignalR | ❌ | ✔️ |
Suporte a clientes MessagePack | desde v1.21.0 | desde v1.20.0 |
Repetir erro transitório | desde v1.22.0 | ❌ |
Os recursos só vêm com uma nova API
Recurso | Transitório | Persistente |
---|---|---|
Verificar se existe uma conexão | ✔️ | Desde v1.11 |
Verificar se existe um grupo | ✔️ | Desde v1.11 |
Verificar se existe um usuário | ✔️ | Desde v1.11 |
Fechar uma conexão de cliente | ✔️ | Desde v1.11 |
Mais detalhes sobre diferentes modos podem ser encontrados aqui.
Um exemplo completo do SDK de gerenciamento pode ser encontrado aqui.
Uso
Esta seção mostra como usar o SDK de Gerenciamento.
Criar Gerenciador de Serviços
Crie sua instância de ServiceManager
a partir de um ServiceManagerBuilder
.
As cadeias de conexão brutas aparecem neste artigo apenas para fins de demonstração. Em ambientes de produção, sempre proteja suas chaves de acesso. Use o Azure Key Vault para gerenciar e girar suas chaves com segurança e proteger sua cadeia de conexão usando o Microsoft Entra ID e autorizar o acesso com o Microsoft Entra ID.
var serviceManager = new ServiceManagerBuilder()
.WithOptions(option =>
{
option.ConnectionString = "<Your Azure SignalR Service Connection String>";
})
.WithLoggerFactory(loggerFactory)
.BuildServiceManager();
Você pode usar ServiceManager
para verificar a integridade do ponto de extremidade do Azure SignalR e criar o contexto do hub de serviço. A seção a seguir fornece detalhes sobre como criar o contexto do hub de serviço.
Para verificar a integridade do ponto de extremidade do Azure SignalR, você pode usar o método ServiceManager.IsServiceHealthy
. Se você tiver vários pontos de extremidade do Azure SignalR, somente o primeiro ponto de extremidade será verificado.
var health = await serviceManager.IsServiceHealthy(cancellationToken);
Criar contexto do Hub de Serviço
Crie sua instância de ServiceHubContext
a partir doServiceManager
:
var serviceHubContext = await serviceManager.CreateHubContextAsync("<Your Hub Name>",cancellationToken);
Negociação
No modo padrão, um ponto de extremidade /<Your Hub Name>/negotiate
é exposto para negociação pelo SDK do Serviço do Azure SignalR. Os clientes do SignalR chegam a esse ponto de extremidade e, em seguida, redirecionam para o Serviço do Azure SignalR mais tarde.
No modo sem servidor, recomendamos que você hospede um ponto de extremidade de negociação para atender à solicitação de negociação dos clientes do SignalR e redirecione os clientes para o Serviço do Azure SignalR.
Dica
Leia mais detalhes sobre o redirecionamento no Protocolo de Negociação do SignalR.
Tanto o ponto de extremidade quanto o token de acesso são úteis quando você deseja redirecionar os clientes do SignalR para o Serviço do Azure SignalR.
Você pode usar a instância de ServiceHubContext
para gerar a URL do ponto de extremidade e o token de acesso correspondente para clientes do SignalR se conectarem ao serviço do Azure SignalR.
var negotiationResponse = await serviceHubContext.NegotiateAsync(new (){UserId = "<Your User Id>"});
Suponha que o ponto de extremidade do hub seja http://<Your Host Name>/<Your Hub Name>
, então seu ponto de extremidade de negociação será http://<Your Host Name>/<Your Hub Name>/negotiate
. Depois de hospedar o ponto de extremidade de negociação, você pode usar os clientes do SignalR para se conectar ao seu hub da seguinte maneira:
var connection = new HubConnectionBuilder().WithUrl("http://<Your Host Name>/<Your Hub Name>").Build();
await connection.StartAsync();
O exemplo de como usar o SDK de Gerenciamento para redirecionar clientes do SignalR para o Serviço do Azure SignalR pode ser encontrado aqui.
Enviar mensagens e gerenciar grupos
O ServiceHubContext
que criamos de ServiceHubContextBuilder
é uma classe que implementa e estende IServiceHubContext
. Você pode usá-lo para enviar mensagens para seus clientes e gerenciar seus grupos.
try
{
// Broadcast
await hubContext.Clients.All.SendAsync(callbackName, obj1, obj2, ...);
// Send to user
await hubContext.Clients.User(userId).SendAsync(callbackName, obj1, obj2, ...);
// Send to group
await hubContext.Clients.Group(groupId).SendAsync(callbackName, obj1, obj2, ...);
// add user to group
await hubContext.UserGroups.AddToGroupAsync(userId, groupName);
// remove user from group
await hubContext.UserGroups.RemoveFromGroupAsync(userId, groupName);
}
finally
{
await hubContext.DisposeAsync();
}
Hub fortemente tipado
Um hub fortemente tipado é um modelo de programação em que você pode extrair seus métodos de cliente em uma interface, para evitar erros como erro de ortografia do nome do método ou passagem dos tipos de parâmetro incorretos.
Digamos que temos um método cliente chamado ReceivedMessage
com dois parâmetros de cadeia de caracteres. Sem hubs fortemente tipado, você transmite para clientes por meio de hubContext.Clients.All.SendAsync("ReceivedMessage", user, message)
. Com hubs fortemente tipado, primeiro você define uma interface como esta:
public interface IChatClient
{
Task ReceiveMessage(string user, string message);
}
E, em seguida, você cria um contexto de hub fortemente tipado, que implementa IHubContext<Hub<T>, T>
, T
é a interface do método cliente:
ServiceHubContext<IChatClient> serviceHubContext = await serviceManager.CreateHubContextAsync<IChatClient>(hubName, cancellationToken);
Por fim, você pode invocar diretamente o método:
await Clients.All.ReceiveMessage(user, message);
Exceto pela diferença de envio de mensagens, você pode negociar ou gerenciar grupos com ServiceHubContext<T>
exatamente como ServiceHubContext
.
Leia mais sobre hubs fortemente tipado nos documentos do ASP.NET Core aqui.
Tipo de transporte
Esse SDK pode se comunicar com o Serviço do Azure SignalR com dois tipos de transporte:
- Transitório: crie uma solicitação Http do Serviço do Azure SignalR para cada mensagem enviada. O SDK simplesmente encapsula a API REST de Serviço do Azure SignalR no modo transitório. É útil quando você não consegue estabelecer uma conexão WebSockets.
- Persistente: crie uma conexão WebSockets primeiro e, em seguida, envie todas as mensagens nessa conexão. É útil quando você envia um grande número de mensagens.
Resumo dos comportamentos de serialização dos argumentos em mensagens
Serialização | Transitório | Persistente |
---|---|---|
Biblioteca JSON padrão | Newtonsoft.Json |
O mesmo que ASP.NET Core SignalR: Newtonsoft.Json para .NET Standard 2.0; System.Text.Json para o aplicativo .NET Core 3.1 e superior |
Suporte a clientes MessagePack | desde v1.21.0 | desde v1.20.0 |
Serialização JSON
No SDK de Gerenciamento, os argumentos de método enviados aos clientes são serializados em JSON. Temos várias maneiras de personalizar a serialização JSON. Mostramos todas as maneiras na ordem desde as mais recomendadas até as menos recomendadas.
ServiceManagerOptions.UseJsonObjectSerializer(ObjectSerializer objectSerializer)
A maneira mais recomendada é usar uma classe abstrata geral ObjectSerializer
, pois dá suporte a diferentes bibliotecas de serialização JSON, como System.Text.Json
e Newtonsoft.Json
e se aplica a todos os tipos de transporte. Normalmente, você não precisa implementar ObjectSerializer
porque implementações JSON úteis para System.Text.Json
e Newtonsoft.Json
já são fornecidas.
Ao usar
System.Text.Json
como biblioteca de processamento JSON, o builtinJsonObjectSerializer
usaSystem.Text.Json.JsonSerializer
para serialização/desserialização. Aqui está um exemplo para usar a nomenclatura de maiúsculas e minúsculas para serialização JSON:var serviceManager = new ServiceManagerBuilder() .WithOptions(o => { o.ConnectionString = "***"; o.UseJsonObjectSerializer(new JsonObjectSerializer(new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase })); }) .BuildServiceManager();
Ao usar
Newtonsoft.Json
como biblioteca de processamento JSON, primeiro instale o pacoteMicrosoft.Azure.Core.NewtonsoftJson
do NuGet usando a CLI do .NET:dotnet add package Microsoft.Azure.Core.NewtonsoftJson
Aqui está um exemplo para usar a nomenclatura de maiúsculas e minúsculas com
NewtonsoftJsonObjectSerializer
:var serviceManager = new ServiceManagerBuilder() .WithOptions(o => { o.ConnectionString = "***"; o.UseJsonObjectSerializer(new NewtonsoftJsonObjectSerializer(new JsonSerializerSettings() { ContractResolver = new CamelCasePropertyNamesContractResolver() })); }) .BuildServiceManager();
Ao usar outras bibliotecas de processamento JSON
Você também pode implementar
ObjectSerializer
por conta própria. Os links a seguir podem ajudar:
ServiceManagerBuilder.WithNewtonsoftJson(Action<NewtonsoftServiceHubProtocolOptions> configure)
Esse método é somente para usuários Newtonsoft.Json
. Aqui está um exemplo para usar a nomenclatura de maiúsculas e minúsculas:
var serviceManager = new ServiceManagerBuilder()
.WithNewtonsoftJson(o =>
{
o.PayloadSerializerSettings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
})
.BuildServiceManager();
ServiceManagerOptions.JsonSerializerSettings
(Preterido)
ServiceManagerOptions.JsonSerializerSettings
Esse método só se aplica ao tipo de transporte transitório. Não use isso.
var serviceManager = new ServiceManagerBuilder()
.WithOptions(o =>
{
o.JsonSerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
})
.BuildServiceManager();
Serialização do Pacote de Mensagens
Você precisa instalar o pacote
Microsoft.AspNetCore.SignalR.Protocols.MessagePack
.Para adicionar um protocolo MessagePack lado a lado com o protocolo JSON padrão:
var serviceManagerBuilder = new ServiceManagerBuilder() .AddHubProtocol(new MessagePackHubProtocol());
Para controlar totalmente os protocolos do hub, você pode usar
var serviceManagerBuilder = new ServiceManagerBuilder() .WithHubProtocols(new MessagePackHubProtocol(), new JsonHubProtocol());
WithHubProtocols
primeiro limpa os protocolos existentes e, em seguida, adiciona os novos protocolos. Você também pode usar esse método para remover o protocolo JSON e usar somente MessagePack.
Para o modo transitório, por padrão, o lado do serviço converte o conteúdo JSON no conteúdo do MessagePack e é a maneira herdada de dar suporte ao MessagePack. No entanto, recomendamos que você adicione um protocolo de hub MessagePack explicitamente, pois a maneira herdada pode não funcionar conforme o esperado.
Nova tentativa de solicitações HTTP
Para o modo transitório, esse SDK fornece a capacidade de reenviar solicitações automaticamente quando ocorrerem erros transitórios, desde que as solicitações sejam idempotentes. Para habilitar essa funcionalidade, você pode usar a propriedade ServiceManagerOptions.RetryOptions
.
Em particular, os seguintes tipos de solicitações são repetidos:
Para solicitações de mensagem que enviam mensagens para clientes do SignalR, o SDK repetirá a solicitação se o código de status de resposta HTTP for maior que 500. Quando o código de resposta HTTP é igual a 500, ele pode indicar um tempo limite no lado do serviço e tentar novamente a solicitação pode resultar em mensagens duplicadas.
Para outros tipos de solicitações, como adicionar uma conexão a um grupo, o SDK repete a solicitação nas seguintes condições:
- O código de status de resposta HTTP está no intervalo 5xx ou a solicitação atingiu o tempo limite com um código de status 408 (Tempo limite da solicitação).
- A solicitação atingiu o tempo limite com uma duração maior do que o tempo limite configurado em
ServiceManagerOptions.HttpClientTimeout
.
O SDK só pode repetir solicitações idempotentes, que são solicitações que não têm outro efeito se forem repetidas. Se suas solicitações não forem idempotentes, talvez seja necessário lidar com novas tentativas manualmente.
Próximas etapas
Neste artigo, você aprendeu como usar o Serviço do SignalR em seus aplicativos. Consulte os seguintes artigos para saber mais sobre o Serviço do SignalR.