Estoy tratando de establecer una conexión entre mi aplicación ASP.NET Core 3.0 Blazor (del lado del servidor) y el servicio Azure SignalR. Terminaré inyectando mi cliente (servicio) SignalR en algunos componentes de Blazor para que actualicen mi UI / DOM en tiempo real.
Mi problema es que recibo el siguiente mensaje cuando llamo a mi .StartAsync()
método en la conexión del concentrador:
El código de estado de respuesta no indica éxito: 404 (no encontrado).
BootstrapSignalRClient.cs
Este archivo carga mi configuración para el servicio SignalR, incluida la URL, la cadena de conexión, la clave, el nombre del método y el nombre del concentrador. Estas configuraciones se capturan en la clase estática SignalRServiceConfiguration
y se usan más tarde.
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);
}
}
Tengo experiencia en el uso de SignalR con .NET Core donde lo agrega para que el Startup.cs
archivo que usa .AddSignalR().AddAzureSignalR()
y asigne un concentrador en la configuración de la aplicación y lo haga de esta manera requiere que se establezcan ciertos parámetros de 'configuración' (es decir, cadena de conexión).
Dada mi situación, ¿de dónde HubConnectionBuilder
obtiene la cadena de conexión o una clave para autenticarse en el servicio SignalR?
¿Es posible que el mensaje 404 sea el resultado de la clave / cadena de conexión que falta?
fuente
.WithUrl(signalRConfig.Url + signalRConfig.HubName)
¿Puedes verificar que esto está dando como resultado la URL correcta? (¿Por punto de corte o registro?)Uri
y construir el completo a través de Uri (Uri, string)Respuestas:
De acuerdo, resulta que la documentación carece de información clave aquí. Si usa el cliente .NET SignalR que se conecta al servicio Azure SignalR, debe solicitar un token JWT y presentarlo al crear la conexión del concentrador.
Si necesita autenticarse en nombre de un usuario, puede usar este ejemplo.
De lo contrario, puede configurar un punto final "/ negociar" utilizando una API web como una función de Azure para recuperar un token JWT y la URL del cliente por usted; Esto es lo que terminé haciendo para mi caso de uso. Aquí puede encontrar información sobre cómo crear una función de Azure para obtener su token JWT y URL .
Creé una clase para mantener estos dos valores como tales:
SignalRConnectionInfo.cs
También creé un método dentro de mi
SignalRService
para manejar la interacción con el punto final "/ negociar" de la API web en Azure, la instanciación de la conexión del concentrador y el uso de un evento + delegado para recibir mensajes de la siguiente manera:SignalRClient.cs
El
functionsClient
es simplemente unHttpClient
preconfigurado fuertemente tipado con una URL base yFunctionsClientConstants.SignalR
es una clase estática con la ruta "/ negociar" que se agrega a la URL base.Una vez que configuré todo esto, llamé al
await hubConnection.StartAsync();
y se "conectó".Después de todo esto, configuré un
ReceiveMessage
evento estático y un delegado de la siguiente manera (en el mismoSignalRClient.cs
):Por último, implementé el
ReceiveMessage
delegado:¡He proporcionado actualizaciones de documentación al equipo del Servicio Azure SignalR y espero que esto ayude a alguien más!
fuente