Estou tentando fazer uma conexão entre meu aplicativo ASP.NET Core 3.0 Blazor (lado do servidor) e o Serviço SignalR do Azure. Acabarei injetando meu cliente SignalR (serviço) em alguns componentes do Blazor para que eles atualizem minha UI / DOM em tempo real.
Meu problema é que estou recebendo a seguinte mensagem quando ligo meu .StartAsync()
método na conexão do hub:
O código de status da resposta não indica sucesso: 404 (Não encontrado).
BootstrapSignalRClient.cs
Este arquivo carrega minha configuração para o Serviço SignalR, incluindo URL, cadeia de conexão, chave, nome do método e nome do hub. Essas configurações são capturadas na classe estática SignalRServiceConfiguration
e usadas posteriormente.
public static class BootstrapSignalRClient
{
public static IServiceCollection AddSignalRServiceClient(this IServiceCollection services, IConfiguration configuration)
{
SignalRServiceConfiguration signalRServiceConfiguration = new SignalRServiceConfiguration();
configuration.Bind(nameof(SignalRServiceConfiguration), signalRServiceConfiguration);
services.AddSingleton(signalRServiceConfiguration);
services.AddSingleton<ISignalRClient, SignalRClient>();
return services;
}
}
SignalRServiceConfiguration.cs
public class SignalRServiceConfiguration
{
public string ConnectionString { get; set; }
public string Url { get; set; }
public string MethodName { get; set; }
public string Key { get; set; }
public string HubName { get; set; }
}
SignalRClient.cs
public class SignalRClient : ISignalRClient
{
public delegate void ReceiveMessage(string message);
public event ReceiveMessage ReceiveMessageEvent;
private HubConnection hubConnection;
public SignalRClient(SignalRServiceConfiguration signalRConfig)
{
hubConnection = new HubConnectionBuilder()
.WithUrl(signalRConfig.Url + signalRConfig.HubName)
.Build();
}
public async Task<string> StartListening(string id)
{
// Register listener for a specific id
hubConnection.On<string>(id, (message) =>
{
if (ReceiveMessageEvent != null)
{
ReceiveMessageEvent.Invoke(message);
}
});
try
{
// Start the SignalR Service connection
await hubConnection.StartAsync(); //<---I get an exception here
return hubConnection.State.ToString();
}
catch (Exception ex)
{
return ex.Message;
}
}
private void ReceiveMessage(string message)
{
response = JsonConvert.DeserializeObject<dynamic>(message);
}
}
Tenho experiência no uso do SignalR com o .NET Core, onde você o adiciona para que o Startup.cs
arquivo que use .AddSignalR().AddAzureSignalR()
e mapeie um hub na configuração do aplicativo e faça dessa maneira exija que certos parâmetros de 'configuração' sejam estabelecidos (ou seja, cadeia de conexão).
Dada a minha situação, onde é HubConnectionBuilder
que a cadeia de conexão ou uma chave se autentica no Serviço SignalR?
É possível que a mensagem 404 seja o resultado da falta da chave / cadeia de conexão?
fonte
.WithUrl(signalRConfig.Url + signalRConfig.HubName)
Você pode verificar se isso está resultando no URL correto? (Por ponto de interrupção ou registro em log?) #Uri
e construir o completo via Uri (Uri, string) #Respostas:
Ok, então a documentação está faltando uma parte importante das informações aqui. Se você estiver usando o .NET SignalR Client que está se conectando ao Serviço SignalR do Azure, precisará solicitar um token JWT e apresentá-lo ao criar a conexão do hub.
Se você precisar se autenticar em nome de um usuário, poderá usar este exemplo.
Caso contrário, você pode configurar um ponto de extremidade "/ negociar" usando uma API da web, como uma Função do Azure, para recuperar um token JWT e uma URL do cliente para você; foi isso que acabei fazendo no meu caso de uso. Informações sobre como criar uma Função do Azure para obter seu token e URL JWT podem ser encontradas aqui.
Eu criei uma classe para armazenar esses dois valores como tal:
SignalRConnectionInfo.cs
Também criei um método dentro do meu
SignalRService
para lidar com a interação com o terminal "/ negociar" da API da Web no Azure, a instanciação da conexão do hub e o uso de um evento + delegado para receber mensagens da seguinte maneira:SignalRClient.cs
A
functionsClient
é simplesmente uma rigidez de tiposHttpClient
pré-configurado com um URL de base e aFunctionsClientConstants.SignalR
é uma classe estática com o "/ negociar" caminho que é acrescentado ao URL de base.Depois de configurar tudo, liguei para o
await hubConnection.StartAsync();
e "conectado"!Depois de tudo isso, configurei um
ReceiveMessage
evento estático e um delegado da seguinte forma (na mesmaSignalRClient.cs
):Por fim, implementei o
ReceiveMessage
delegado:Forneci atualizações de documentação à equipe do Serviço SignalR do Azure e espero que isso ajude outra pessoa!
fonte