Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
A biblioteca de cliente .NET do ASP.NET Core SignalR permite que você se comunique com SignalR hubs de aplicativos .NET.
Visualizar ou descarregar amostra de código (como descarregar)
O exemplo de código neste artigo é um aplicativo WPF que usa o cliente .NET ASP.NET Core SignalR .
Instalar o pacote cliente SignalR .NET
O pacote Microsoft.AspNetCore.SignalR.Client é necessário para que os clientes .NET se conectem a SignalR hubs.
Para instalar a biblioteca de cliente, execute o seguinte comando na janela Console do Gerenciador de Pacotes :
Install-Package Microsoft.AspNetCore.SignalR.Client
Conectar-se a um hub
Para estabelecer uma conexão, crie um HubConnectionBuilder e chame Build. A URL do hub, o protocolo, o tipo de transporte, o nível de log, os cabeçalhos e outras opções podem ser configurados durante a criação de uma conexão. Configure todas as opções necessárias inserindo qualquer um dos HubConnectionBuilder métodos no Build. Inicie a conexão com StartAsync.
using System;
using System.Threading.Tasks;
using System.Windows;
using Microsoft.AspNetCore.SignalR.Client;
namespace SignalRChatClient
{
public partial class MainWindow : Window
{
HubConnection connection;
public MainWindow()
{
InitializeComponent();
connection = new HubConnectionBuilder()
.WithUrl("http://localhost:53353/ChatHub")
.Build();
connection.Closed += async (error) =>
{
await Task.Delay(new Random().Next(0,5) * 1000);
await connection.StartAsync();
};
}
private async void connectButton_Click(object sender, RoutedEventArgs e)
{
connection.On<string, string>("ReceiveMessage", (user, message) =>
{
this.Dispatcher.Invoke(() =>
{
var newMessage = $"{user}: {message}";
messagesList.Items.Add(newMessage);
});
});
try
{
await connection.StartAsync();
messagesList.Items.Add("Connection started");
connectButton.IsEnabled = false;
sendButton.IsEnabled = true;
}
catch (Exception ex)
{
messagesList.Items.Add(ex.Message);
}
}
private async void sendButton_Click(object sender, RoutedEventArgs e)
{
try
{
await connection.InvokeAsync("SendMessage",
userTextBox.Text, messageTextBox.Text);
}
catch (Exception ex)
{
messagesList.Items.Add(ex.Message);
}
}
}
}
Lidar com a perda de conexão
Reconecte-se automaticamente
O HubConnection pode ser configurado para a reconexão automática usando o método WithAutomaticReconnect no HubConnectionBuilder. Ele não se reconectará automaticamente por padrão.
HubConnection connection= new HubConnectionBuilder()
.WithUrl(new Uri("http://127.0.0.1:5000/chathub"))
.WithAutomaticReconnect()
.Build();
Sem quaisquer parâmetros, WithAutomaticReconnect() configura o cliente para aguardar 0, 2, 10 e 30 segundos, respectivamente, antes de tentar cada tentativa de reconexão, parando após quatro tentativas falhadas.
Antes de iniciar qualquer tentativa de reconexão, o HubConnection fará a transição para o HubConnectionState.Reconnecting estado e disparará o Reconnecting evento. Isso oferece uma oportunidade para avisar os usuários que a conexão foi perdida e desabilitar os elementos da interface do usuário. As aplicações não interativas podem começar a enfileirar ou soltar mensagens.
connection.Reconnecting += error =>
{
Debug.Assert(connection.State == HubConnectionState.Reconnecting);
// Notify users the connection was lost and the client is reconnecting.
// Start queuing or dropping messages.
return Task.CompletedTask;
};
Se o cliente se reconectar com êxito nas suas primeiras quatro tentativas, a transição HubConnection voltará ao estado Connected e disparará o evento Reconnected. Isso oferece uma oportunidade de informar aos usuários que a conexão foi restabelecida e retirar da fila todas as mensagens enfileiradas.
Como a conexão é percebida como totalmente nova para o servidor, uma nova ConnectionId será fornecida aos manipuladores de eventos Reconnected.
Warning
O parâmetro do Reconnected manipulador de eventos será nulo se o connectionId foi configurado para HubConnection a negociação.
connection.Reconnected += connectionId =>
{
Debug.Assert(connection.State == HubConnectionState.Connected);
// Notify users the connection was reestablished.
// Start dequeuing messages queued while reconnecting if any.
return Task.CompletedTask;
};
WithAutomaticReconnect() não configurará o para repetir as HubConnection falhas iniciais de inicialização, portanto, as falhas de inicialização precisam ser tratadas manualmente:
public static async Task<bool> ConnectWithRetryAsync(HubConnection connection, CancellationToken token)
{
// Keep trying to until we can start or the token is canceled.
while (true)
{
try
{
await connection.StartAsync(token);
Debug.Assert(connection.State == HubConnectionState.Connected);
return true;
}
catch when (token.IsCancellationRequested)
{
return false;
}
catch
{
// Failed to connect, trying again in 5000 ms.
Debug.Assert(connection.State == HubConnectionState.Disconnected);
await Task.Delay(5000);
}
}
}
Se o cliente não se reconectar com êxito nas suas primeiras quatro tentativas, o HubConnection fará a transição para o estado Disconnected e disparará o evento Closed. Isso oferece uma oportunidade de tentar reiniciar a conexão manualmente ou informar aos usuários que a conexão foi perdida permanentemente.
connection.Closed += error =>
{
Debug.Assert(connection.State == HubConnectionState.Disconnected);
// Notify users the connection has been closed or manually try to restart the connection.
return Task.CompletedTask;
};
Para configurar um número personalizado de tentativas de reconexão antes de desconectar ou alterar o tempo de reconexão, WithAutomaticReconnect aceita uma matriz de números que representam o atraso em milissegundos para aguardar antes de iniciar cada tentativa de reconexão.
HubConnection connection = new HubConnectionBuilder()
.WithUrl(new Uri("http://127.0.0.1:5000/chathub"))
.WithAutomaticReconnect(new[] { TimeSpan.Zero, TimeSpan.Zero, TimeSpan.FromSeconds(10) })
.Build();
// .WithAutomaticReconnect(new[] { TimeSpan.Zero, TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(30) }) yields the default behavior.
O exemplo anterior configura o HubConnection para iniciar tentativas de reconexão imediatamente após a perda de conexão. Isso também é verdadeiro para a configuração padrão.
Se a primeira tentativa de reconexão falhar, a segunda tentativa de reconexão também será iniciada imediatamente, em vez de esperar 2 segundos, como faria na configuração padrão.
Se a segunda tentativa de reconexão falhar, a terceira tentativa de reconexão será iniciada em 10 segundos, o que é novamente como a configuração padrão.
Em seguida, o comportamento personalizado diverge novamente do comportamento padrão, parando após a falha da terceira tentativa de reconexão. Na configuração padrão, haveria mais uma tentativa de reconexão em mais 30 segundos.
Se você quiser ainda mais controle sobre o tempo e o número de tentativas de reconexão automática, WithAutomaticReconnect aceita um objeto que implementa a IRetryPolicy interface, que tem um único método chamado NextRetryDelay.
NextRetryDelay usa um único argumento com o tipo RetryContext. O RetryContext tem três propriedades: PreviousRetryCount, ElapsedTime e RetryReason, que são um long, a TimeSpan e um Exception respectivamente. Antes da primeira tentativa de nova conexão, PreviousRetryCount e ElapsedTime serão zero, e RetryReason será a Exceção que causou a perda da conexão. Depois de cada tentativa de repetição falhada, PreviousRetryCount será incrementado por um, ElapsedTime será atualizado para refletir a quantidade de tempo gasto reconectando até agora e a RetryReason Exceção que causou a falha da última tentativa de reconexão.
NextRetryDelay deve retornar um TimeSpan representando o tempo de espera antes da próxima tentativa de reconexão ou null se o deve parar de HubConnection se reconectar.
public class RandomRetryPolicy : IRetryPolicy
{
private readonly Random _random = new Random();
public TimeSpan? NextRetryDelay(RetryContext retryContext)
{
// If we've been reconnecting for less than 60 seconds so far,
// wait between 0 and 10 seconds before the next reconnect attempt.
if (retryContext.ElapsedTime < TimeSpan.FromSeconds(60))
{
return TimeSpan.FromSeconds(_random.NextDouble() * 10);
}
else
{
// If we've been reconnecting for more than 60 seconds so far, stop reconnecting.
return null;
}
}
}
HubConnection connection = new HubConnectionBuilder()
.WithUrl(new Uri("http://127.0.0.1:5000/chathub"))
.WithAutomaticReconnect(new RandomRetryPolicy())
.Build();
Como alternativa, você pode escrever código que reconectará seu cliente manualmente, conforme demonstrado em Reconectar manualmente.
Reconectar manualmente
Warning
Antes da versão 3.0, o cliente .NET para SignalR não se reconecta automaticamente. Você deve escrever um código que reconectará seu cliente manualmente.
Use o Closed evento para responder a uma conexão perdida. Por exemplo, talvez você queira automatizar a reconexão.
O Closed evento requer um delegado que retorna um Task, que permite que o código assíncrono seja executado sem usar async voido . Para satisfazer a assinatura do delegado em um Closed manipulador de eventos executado de forma síncrona, retorne Task.CompletedTask:
connection.Closed += (error) => {
// Do your close logic.
return Task.CompletedTask;
};
A principal razão para o suporte assíncrono é para que você possa reiniciar a conexão. Iniciar uma conexão é uma ação assíncrona.
Em um Closed manipulador que reinicia a conexão, considere aguardar algum atraso aleatório para evitar sobrecarregar o servidor, conforme mostrado no exemplo a seguir:
connection.Closed += async (error) =>
{
await Task.Delay(new Random().Next(0,5) * 1000);
await connection.StartAsync();
};
Chamar métodos do hub a partir do cliente
InvokeAsync chama métodos no hub. Passe o nome do método hub e quaisquer argumentos definidos no método hub para InvokeAsync.
SignalR é assíncrono, por isso use async e await ao fazer as chamadas.
await connection.InvokeAsync("SendMessage",
userTextBox.Text, messageTextBox.Text);
O InvokeAsync método retorna um Task que é finalizado quando o método do servidor retorna. O valor de retorno, se houver, é fornecido como resultado do Task. Quaisquer exceções lançadas pelo método no servidor produzem uma falha Task. Use a sintaxe await para aguardar a conclusão do método do servidor e a sintaxe try...catch para manipular erros.
O SendAsync método retorna um Task que é concluído quando a mensagem foi enviada para o servidor. Nenhum valor de retorno é fornecido, pois isso Task não espera até que o método do servidor seja concluído. Quaisquer exceções lançadas no cliente ao enviar a mensagem resultam em um erro Task. Use a sintaxe de await e try...catch para lidar com erros de envio.
Note
A chamada de métodos de hub a partir de um cliente só é suportada ao utilizar o Serviço SignalR do Azure no modo Padrão. Para obter mais informações, consulte Perguntas frequentes.
Chamar métodos de cliente a partir do hub
Defina métodos que o hub chama usando connection.On após a criação, mas antes de iniciar a conexão.
connection.On<string, string>("ReceiveMessage", (user, message) =>
{
this.Dispatcher.Invoke(() =>
{
var newMessage = $"{user}: {message}";
messagesList.Items.Add(newMessage);
});
});
O código anterior é executado connection.On quando o código do lado do servidor o chama usando o método SendAsync.
public async Task SendMessage(string user, string message)
{
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
Note
Embora o lado do hub da conexão ofereça suporte a mensagens fortemente tipadas, o cliente deve se registrar usando o método genérico HubConnection.On, especificando o nome do método. Para obter um exemplo, consulte Host ASP.NET Core SignalR em serviços em segundo plano.
Tratamento e registo de erros
Manipule erros com uma instrução try-catch. Inspecione o Exception objeto para determinar a ação adequada a ser tomada após a ocorrência de um erro.
try
{
await connection.InvokeAsync("SendMessage",
userTextBox.Text, messageTextBox.Text);
}
catch (Exception ex)
{
messagesList.Items.Add(ex.Message);
}