Guía de SignalR de Blazor para ASP.NET Core
En este artículo se explica cómo configurar y administrar conexiones de SignalR en aplicaciones Blazor.
Para obtener instrucciones generales sobre la configuración de SignalR para ASP.NET Core, consulte los temas del área Introducción a ASP.NET Core SignalR de la documentación. Para configurar SignalR agregado a una solución de Blazor WebAssembly hospedada, vea Configuración de SignalR en ASP.NET Core.
Negociación entre orígenes de SignalR para la autenticación
Para configurar el cliente subyacente de SignalR para que envíe credenciales, como cookies o encabezados de autenticación HTTP:
Use SetBrowserRequestCredentials para establecer Include en solicitudes de
fetchentre orígenes.IncludeRequestCredentialsMessageHandler.cs:using System.Net.Http; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Components.WebAssembly.Http; public class IncludeRequestCredentialsMessageHandler : DelegatingHandler { protected override Task<HttpResponseMessage> SendAsync( HttpRequestMessage request, CancellationToken cancellationToken) { request.SetBrowserRequestCredentials(BrowserRequestCredentials.Include); return base.SendAsync(request, cancellationToken); } }Si existe una conexión con un centro, asigne HttpMessageHandler a la opción HttpMessageHandlerFactory:
HubConnectionBuilder hubConnecton; ... hubConnecton = new HubConnectionBuilder() .WithUrl(new Uri(NavigationManager.ToAbsoluteUri("/chathub")), options => { options.HttpMessageHandlerFactory = innerHandler => new IncludeRequestCredentialsMessageHandler { InnerHandler = innerHandler }; }).Build();En el ejemplo anterior, la dirección URL de la conexión del centro se configura en el URI absoluto en
/chathub, que es la dirección URL que se usa en el tutorial de SignalR con Blazor en el componenteIndex(Pages/Index.razor). El URI también se puede establecer por medio de una cadena (por ejemplo,https://signalr.example.com) o mediante configuración.
Para obtener más información, vea Configuración de SignalR en ASP.NET Core.
Modo de representación
Si una aplicación Blazor WebAssembly que usa SignalR se configura para que se represente previamente en el servidor, se producirá una representación previa antes de establecer la conexión del cliente con el servidor. Para más información, vea los siguientes artículos:
- Asistente de etiquetas de componente en ASP.NET Core
- Integración y representación previa de componentes Razor de ASP.NET Core
Recursos adicionales
En este artículo se explica cómo configurar y administrar conexiones de SignalR en aplicaciones Blazor.
Para obtener instrucciones generales sobre la configuración de SignalR para ASP.NET Core, consulte los temas del área Introducción a ASP.NET Core SignalR de la documentación. Para configurar SignalR agregado a una solución de Blazor WebAssembly hospedada, vea Configuración de SignalR en ASP.NET Core.
Opciones de controlador de circuito
Configure el circuito Blazor Server con los valores de CircuitOptions que se muestran en la tabla siguiente.
| Opción | Valor predeterminado | Descripción |
|---|---|---|
| DetailedErrors | false |
Envío de mensajes de excepción detallados a JavaScript cuando se produce una excepción no controlada en el circuito o cuando una invocación de método de .NET a través de la interoperabilidad de JS produce una excepción. |
| DisconnectedCircuitMaxRetained | 100 | Número máximo de circuitos desconectados que el servidor contiene en la memoria cada vez. |
| DisconnectedCircuitRetentionPeriod | 3 minutos | Cantidad máxima de tiempo que un circuito desconectado se conserva en la memoria antes de desactivarlo. |
| JSInteropDefaultCallTimeout | 1 minuto | Cantidad máxima de tiempo que el servidor aguarda antes de agotar el tiempo de espera de invocación de una función de JavaScript asincrónica. |
| MaxBufferedUnacknowledgedRenderBatches | 10 | Número máximo de lotes de representación no confirmados por circuito que el servidor mantiene en la memoria en un momento dado para admitir una reconexión sólida. Después de alcanzar el límite, el servidor deja de generar nuevos lotes de representación hasta que el cliente confirme uno o varios lotes. |
Configure las opciones de Program.cs con un delegado de opciones en AddServerSideBlazor. En el siguiente ejemplo se asignan los valores de opción predeterminados que se muestran en la tabla anterior. Confirme que Program.cs usa el espacio de nombres System (using System;).
En Program.cs:
builder.Services.AddServerSideBlazor(options =>
{
options.DetailedErrors = false;
options.DisconnectedCircuitMaxRetained = 100;
options.DisconnectedCircuitRetentionPeriod = TimeSpan.FromMinutes(3);
options.JSInteropDefaultCallTimeout = TimeSpan.FromMinutes(1);
options.MaxBufferedUnacknowledgedRenderBatches = 10;
});
Para configurar HubConnectionContext, use HubConnectionContextOptions con AddHubOptions. Para obtener descripciones de las opciones, vea Configuración de SignalR en ASP.NET Core. En el siguiente ejemplo se asignan los valores de opción predeterminados. Confirme que Program.cs usa el espacio de nombres System (using System;).
En Program.cs:
builder.Services.AddServerSideBlazor()
.AddHubOptions(options =>
{
options.ClientTimeoutInterval = TimeSpan.FromSeconds(30);
options.EnableDetailedErrors = false;
options.HandshakeTimeout = TimeSpan.FromSeconds(15);
options.KeepAliveInterval = TimeSpan.FromSeconds(15);
options.MaximumParallelInvocationsPerClient = 1;
options.MaximumReceiveMessageSize = 32 * 1024;
options.StreamBufferCapacity = 10;
});
Blazor Configuración de la ruta del punto de conexión del centro
En Program.cs, las aplicaciones de Blazor Server llaman a MapBlazorHub para asignar Blazor Hub a la ruta de acceso predeterminada de la aplicación. El script de Blazor Server (blazor.server.js) apunta automáticamente al punto de conexión creado por MapBlazorHub.
Reflejo del estado de la conexión en la interfaz de usuario
Cuando el cliente detecta que se ha perdido la conexión, se muestra al usuario una interfaz de usuario predeterminada mientras el cliente intenta volver a conectarse. Si se produce un error en la reconexión, se proporciona al usuario la opción de volver a intentarlo.
Para personalizar la interfaz de usuario, defina un elemento con un valor de id de components-reconnect-modal en el elemento <body> de la página _Layout.cshtml de Razor.
Pages/_Layout.cshtml:
<div id="components-reconnect-modal">
...
</div>
Agregue los siguientes estilos CSS a la hoja de estilos del sitio.
wwwroot/css/site.css:
#components-reconnect-modal {
display: none;
}
#components-reconnect-modal.components-reconnect-show {
display: block;
}
En la siguiente tabla se describen las clases de CSS que el marco Blazor aplica al elemento components-reconnect-modal.
| Clase de CSS | Indica… |
|---|---|
components-reconnect-show |
Una conexión perdida. El cliente intenta volver a conectarse. Se muestra el modal. |
components-reconnect-hide |
Se restablece una conexión activa con el servidor. Se oculta el modal. |
components-reconnect-failed |
Error de reconexión, probablemente debido a un error de la red. Para intentar la reconexión, llame a window.Blazor.reconnect() en JavaScript. |
components-reconnect-rejected |
Reconexión rechazada. Se ha alcanzado el servidor pero se ha rechazado la conexión y se ha perdido el estado del usuario en el servidor. Para volver a cargar la aplicación, llame a location.reload() en JavaScript. Este estado de conexión se puede producir cuando:
|
Modo de representación
De forma predeterminada, las aplicaciones Blazor Server realizan una representación previa de la interfaz de usuario en el servidor antes de que se establezca la conexión del cliente con él. Para más información, consulte Asistente de etiquetas de componente en ASP.NET Core.
Inicio de Blazor
Configure el inicio manual de un circuito de SignalR de la aplicación Blazor Server en el archivo Pages/_Layout.cshtml:
- Agregue un atributo
autostart="false"a la etiqueta<script>para el scriptblazor.server.js. - Coloque un script que llame a
Blazor.startdespués de la etiqueta<script>del scriptblazor.server.jsy dentro de la etiqueta de cierre</body>.
Cuando autostart está deshabilitado, cualquier aspecto de la aplicación que no depende del circuito funciona normalmente. Por ejemplo, el enrutamiento del lado cliente está operativo. Sin embargo, cualquier aspecto que dependa del circuito no funcionará hasta que se llame a Blazor.start. El comportamiento de la aplicación es imprevisible sin ningún circuito establecido. Por ejemplo, los métodos de componente no se ejecutan mientras el circuito está desconectado.
Para más información, incluida la forma de inicializar Blazor cuando el documento está listo y de encadenar a Promise de JS, vea Inicio de Blazor en ASP.NET Core.
Configuración del registro de cliente de SignalR
En el generador de cliente, pase el objeto de configuración configureSignalR que llama a configureLogging con el nivel de registro.
Pages/_Layout.cshtml:
<body>
...
<script src="_framework/blazor.server.js" autostart="false"></script>
<script>
Blazor.start({
configureSignalR: function (builder) {
builder.configureLogging("information");
}
});
</script>
</body>
En el ejemplo anterior, information es equivalente a un nivel de registro de LogLevel.Information.
Para más información sobre el inicio de Blazor, vea Inicio de Blazor en ASP.NET Core.
Modificación del controlador de reconexión
Los eventos de conexión del circuito del controlador de reconexión pueden modificarse para obtener comportamientos personalizados, por ejemplo:
- Para notificar al usuario si la conexión se ha quitado.
- Para realizar el registro (desde el cliente) cuando un circuito está conectado.
Para modificar los eventos de conexión, registre las devoluciones de llamada para los siguientes cambios de conexión:
- Las conexiones que se quitan usan
onConnectionDown. - Las conexiones establecidas o restablecidas usan
onConnectionUp.
Es necesario especificar tanto onConnectionDown como onConnectionUp .
Pages/_Layout.cshtml:
<body>
...
<script src="_framework/blazor.server.js" autostart="false"></script>
<script>
Blazor.start({
reconnectionHandler: {
onConnectionDown: (options, error) => console.error(error),
onConnectionUp: () => console.log("Up, up, and away!")
}
});
</script>
</body>
Para más información sobre el inicio de Blazor, vea Inicio de Blazor en ASP.NET Core.
Ajustar el número y el intervalo de reintentos de reconexión
Para ajustar el intervalo y el número de reintentos de reconexión, establezca el número de reintentos (maxRetries) y el período en milisegundos permitido en cada reintento (retryIntervalMilliseconds).
Pages/_Layout.cshtml:
<body>
...
<script src="_framework/blazor.server.js" autostart="false"></script>
<script>
Blazor.start({
reconnectionOptions: {
maxRetries: 3,
retryIntervalMilliseconds: 2000
}
});
</script>
</body>
Para más información sobre el inicio de Blazor, vea Inicio de Blazor en ASP.NET Core.
Ocultar o reemplazar la pantalla de reconexión
Para ocultar la presentación de reconexión, establezca el valor _reconnectionDisplay del controlador de reconexión en un objeto vacío ({} o new Object()).
Pages/_Layout.cshtml:
<body>
...
<script src="_framework/blazor.server.js" autostart="false"></script>
<script>
window.addEventListener('beforeunload', function () {
Blazor.defaultReconnectionHandler._reconnectionDisplay = {};
});
Blazor.start();
</script>
</body>
Para reemplazar la pantalla de reconexión, establezca _reconnectionDisplay del ejemplo anterior en el elemento que se va a mostrar:
Blazor.defaultReconnectionHandler._reconnectionDisplay =
document.getElementById("{ELEMENT ID}");
El marcador de posición {ELEMENT ID} es el identificador del elemento HTML que se va a mostrar.
Para más información sobre el inicio de Blazor, vea Inicio de Blazor en ASP.NET Core.
Personalice el retraso antes de que aparezca la pantalla de reconexión. Para ello, establezca la propiedad transition-delay en el CSS del sitio como elemento modal. En el siguiente ejemplo, el retraso de la transición se cambia de 500 ms (valor predeterminado) a 1000 ms (1 segundo).
wwwroot/css/site.css:
#components-reconnect-modal {
transition: visibility 0s linear 1000ms;
}
Desconexión del circuito Blazor del cliente
De forma predeterminada, un circuito Blazor se desconecta cuando se desencadena el evento de página unload. A fin de desconectar el circuito para otros escenarios en el cliente, invoque Blazor.disconnect en el controlador de eventos adecuado. En el ejemplo siguiente, el circuito se desconecta cuando la página está oculta (evento pagehide):
window.addEventListener('pagehide', () => {
Blazor.disconnect();
});
Para más información sobre el inicio de Blazor, vea Inicio de Blazor en ASP.NET Core.
Controlador de circuito de Blazor Server
Blazor Server permite que el código defina un controlador de circuito, que permite ejecutar el código en los cambios realizados en el estado del circuito de un usuario. Un controlador de circuito se implementa derivando de CircuitHandler y registrando la clase en el contenedor de servicios de la aplicación. El ejemplo siguiente de un controlador de circuito realiza un seguimiento de las conexiones abiertas de SignalR.
TrackingCircuitHandler.cs:
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.Server.Circuits;
public class TrackingCircuitHandler : CircuitHandler
{
private HashSet<Circuit> circuits = new();
public override Task OnConnectionUpAsync(Circuit circuit,
CancellationToken cancellationToken)
{
circuits.Add(circuit);
return Task.CompletedTask;
}
public override Task OnConnectionDownAsync(Circuit circuit,
CancellationToken cancellationToken)
{
circuits.Remove(circuit);
return Task.CompletedTask;
}
public int ConnectedCircuits => circuits.Count;
}
Los controladores de circuito se registran mediante DI. Las instancias con ámbito se crean por instancia de un circuito. Mediante el uso de TrackingCircuitHandler en el ejemplo anterior, se crea un servicio singleton porque se debe realizar un seguimiento del estado de todos los circuitos.
Program.cs:
builder.Services.AddSingleton<CircuitHandler, TrackingCircuitHandler>();
Si los métodos de un controlador de circuito personalizado producen una excepción no controlada, la excepción es grave para el circuito de Blazor Server. Para tolerar excepciones en el código de un controlador o en los métodos llamados, encapsule el código en una o varias instrucciones try-catch con control de errores y registro.
Cuando un circuito finaliza porque un usuario se ha desconectado y el marco está limpiando el estado del circuito, el marco desecha el ámbito de DI del circuito. Al desechar el ámbito, se eliminan también todos los servicios de DI con ámbito del circuito que implementan System.IDisposable. Si un servicio de DI produce una excepción no controlada durante la eliminación, el marco registra la excepción.
Azure SignalR Service
Se recomienda usar Azure SignalR Service ´con las aplicaciones Blazor Server hospedadas en Microsoft Azure. El servicio funciona junto con el centro Blazor de la aplicación para escalar verticalmente una aplicación Blazor Server a un gran número de conexiones de SignalR simultáneas. Además, los centros de datos de alto rendimiento y alcance global de SignalR Service son de gran ayuda a la hora de reducir la latencia ocasionada por la geografía. Para obtener compatibilidad con la representación previa con Azure SignalR Service, configure la aplicación para usar sesiones permanentes. Para obtener más información, vea Hospedaje e implementación de ASP.NET Core Blazor Server.
Recursos adicionales
- Introducción a ASP.NET Core SignalR
- Configuración de SignalR en ASP.NET Core
- Guía de mitigación de amenazas para ASP.NET Core Blazor Server
- Eventos de reconexión y de ciclo de vida de componentes de Blazor Server
- ¿Qué es Azure SignalR Service?
- Guía de rendimiento de Azure SignalR Service
- Publicar una aplicación ASP.NET Core SignalR para Azure App Service
En este artículo se explica cómo configurar y administrar conexiones de SignalR en aplicaciones Blazor.
Para obtener instrucciones generales sobre la configuración de SignalR para ASP.NET Core, consulte los temas del área Introducción a ASP.NET Core SignalR de la documentación. Para configurar SignalR agregado a una solución de Blazor WebAssembly hospedada, vea Configuración de SignalR en ASP.NET Core.
Negociación entre orígenes de SignalR para la autenticación
Para configurar el cliente subyacente de SignalR para que envíe credenciales, como cookies o encabezados de autenticación HTTP:
Use SetBrowserRequestCredentials para establecer Include en solicitudes de
fetchentre orígenes.IncludeRequestCredentialsMessageHandler.cs:using System.Net.Http; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Components.WebAssembly.Http; public class IncludeRequestCredentialsMessageHandler : DelegatingHandler { protected override Task<HttpResponseMessage> SendAsync( HttpRequestMessage request, CancellationToken cancellationToken) { request.SetBrowserRequestCredentials(BrowserRequestCredentials.Include); return base.SendAsync(request, cancellationToken); } }Si existe una conexión con un centro, asigne HttpMessageHandler a la opción HttpMessageHandlerFactory:
HubConnectionBuilder hubConnecton; ... hubConnecton = new HubConnectionBuilder() .WithUrl(new Uri(NavigationManager.ToAbsoluteUri("/chathub")), options => { options.HttpMessageHandlerFactory = innerHandler => new IncludeRequestCredentialsMessageHandler { InnerHandler = innerHandler }; }).Build();En el ejemplo anterior, la dirección URL de la conexión del centro se configura en el URI absoluto en
/chathub, que es la dirección URL que se usa en el tutorial de SignalR con Blazor en el componenteIndex(Pages/Index.razor). El URI también se puede establecer por medio de una cadena (por ejemplo,https://signalr.example.com) o mediante configuración.
Para obtener más información, vea Configuración de SignalR en ASP.NET Core.
Modo de representación
Si una aplicación Blazor WebAssembly que usa SignalR se configura para que se represente previamente en el servidor, se producirá una representación previa antes de establecer la conexión del cliente con el servidor. Para más información, vea los siguientes artículos:
- Asistente de etiquetas de componente en ASP.NET Core
- Integración y representación previa de componentes Razor de ASP.NET Core
Recursos adicionales
En este artículo se explica cómo configurar y administrar conexiones de SignalR en aplicaciones Blazor.
Para obtener instrucciones generales sobre la configuración de SignalR para ASP.NET Core, consulte los temas del área Introducción a ASP.NET Core SignalR de la documentación. Para configurar SignalR agregado a una solución de Blazor WebAssembly hospedada, vea Configuración de SignalR en ASP.NET Core.
Opciones de controlador de circuito
Configure el circuito Blazor Server con los valores de CircuitOptions que se muestran en la tabla siguiente.
| Opción | Valor predeterminado | Descripción |
|---|---|---|
| DetailedErrors | false |
Envío de mensajes de excepción detallados a JavaScript cuando se produce una excepción no controlada en el circuito o cuando una invocación de método de .NET a través de la interoperabilidad de JS produce una excepción. |
| DisconnectedCircuitMaxRetained | 100 | Número máximo de circuitos desconectados que el servidor contiene en la memoria cada vez. |
| DisconnectedCircuitRetentionPeriod | 3 minutos | Cantidad máxima de tiempo que un circuito desconectado se conserva en la memoria antes de desactivarlo. |
| JSInteropDefaultCallTimeout | 1 minuto | Cantidad máxima de tiempo que el servidor aguarda antes de agotar el tiempo de espera de invocación de una función de JavaScript asincrónica. |
| MaxBufferedUnacknowledgedRenderBatches | 10 | Número máximo de lotes de representación no confirmados por circuito que el servidor mantiene en la memoria en un momento dado para admitir una reconexión sólida. Después de alcanzar el límite, el servidor deja de generar nuevos lotes de representación hasta que el cliente confirme uno o varios lotes. |
Configure las opciones de Startup.ConfigureServices con un delegado de opciones en AddServerSideBlazor. En el siguiente ejemplo se asignan los valores de opción predeterminados que se muestran en la tabla anterior. Confirme que Startup.cs usa el espacio de nombres System (using System;).
Startup.ConfigureServices:
services.AddServerSideBlazor(options =>
{
options.DetailedErrors = false;
options.DisconnectedCircuitMaxRetained = 100;
options.DisconnectedCircuitRetentionPeriod = TimeSpan.FromMinutes(3);
options.JSInteropDefaultCallTimeout = TimeSpan.FromMinutes(1);
options.MaxBufferedUnacknowledgedRenderBatches = 10;
});
Para configurar HubConnectionContext, use HubConnectionContextOptions con AddHubOptions. Para obtener descripciones de las opciones, vea Configuración de SignalR en ASP.NET Core. En el siguiente ejemplo se asignan los valores de opción predeterminados. Confirme que Startup.cs usa el espacio de nombres System (using System;).
Startup.ConfigureServices:
services.AddServerSideBlazor()
.AddHubOptions(options =>
{
options.ClientTimeoutInterval = TimeSpan.FromSeconds(30);
options.EnableDetailedErrors = false;
options.HandshakeTimeout = TimeSpan.FromSeconds(15);
options.KeepAliveInterval = TimeSpan.FromSeconds(15);
options.MaximumParallelInvocationsPerClient = 1;
options.MaximumReceiveMessageSize = 32 * 1024;
options.StreamBufferCapacity = 10;
});
Blazor Configuración de la ruta del punto de conexión del centro
En Startup.Configure, las aplicaciones de Blazor Server llaman a MapBlazorHub en el objeto IEndpointRouteBuilder de UseEndpoints para asignar Blazor Hub a la ruta de acceso predeterminada de la aplicación. El script de Blazor Server (blazor.server.js) apunta automáticamente al punto de conexión creado por MapBlazorHub.
Reflejo del estado de la conexión en la interfaz de usuario
Cuando el cliente detecta que se ha perdido la conexión, se muestra al usuario una interfaz de usuario predeterminada mientras el cliente intenta volver a conectarse. Si se produce un error en la reconexión, se proporciona al usuario la opción de volver a intentarlo.
Para personalizar la interfaz de usuario, defina un elemento con un valor de id de components-reconnect-modal en el elemento <body> de la página _Host.cshtml de Razor.
Pages/_Host.cshtml:
<div id="components-reconnect-modal">
...
</div>
Agregue los siguientes estilos CSS a la hoja de estilos del sitio.
wwwroot/css/site.css:
#components-reconnect-modal {
display: none;
}
#components-reconnect-modal.components-reconnect-show {
display: block;
}
En la siguiente tabla se describen las clases de CSS que el marco Blazor aplica al elemento components-reconnect-modal.
| Clase de CSS | Indica… |
|---|---|
components-reconnect-show |
Una conexión perdida. El cliente intenta volver a conectarse. Se muestra el modal. |
components-reconnect-hide |
Se restablece una conexión activa con el servidor. Se oculta el modal. |
components-reconnect-failed |
Error de reconexión, probablemente debido a un error de la red. Para intentar la reconexión, llame a window.Blazor.reconnect() en JavaScript. |
components-reconnect-rejected |
Reconexión rechazada. Se ha alcanzado el servidor pero se ha rechazado la conexión y se ha perdido el estado del usuario en el servidor. Para volver a cargar la aplicación, llame a location.reload() en JavaScript. Este estado de conexión se puede producir cuando:
|
Modo de representación
De forma predeterminada, las aplicaciones Blazor Server realizan una representación previa de la interfaz de usuario en el servidor antes de que se establezca la conexión del cliente con él. Para más información, consulte Asistente de etiquetas de componente en ASP.NET Core.
Inicio de Blazor
Configure el inicio manual de un circuito de SignalR de la aplicación Blazor Server en el archivo Pages/_Host.cshtml:
- Agregue un atributo
autostart="false"a la etiqueta<script>para el scriptblazor.server.js. - Coloque un script que llame a
Blazor.startdespués de la etiqueta<script>del scriptblazor.server.jsy dentro de la etiqueta de cierre</body>.
Cuando autostart está deshabilitado, cualquier aspecto de la aplicación que no depende del circuito funciona normalmente. Por ejemplo, el enrutamiento del lado cliente está operativo. Sin embargo, cualquier aspecto que dependa del circuito no funcionará hasta que se llame a Blazor.start. El comportamiento de la aplicación es imprevisible sin ningún circuito establecido. Por ejemplo, los métodos de componente no se ejecutan mientras el circuito está desconectado.
Para más información, incluida la forma de inicializar Blazor cuando el documento está listo y de encadenar a Promise de JS, vea Inicio de Blazor en ASP.NET Core.
Configuración del registro de cliente de SignalR
En el generador de cliente, pase el objeto de configuración configureSignalR que llama a configureLogging con el nivel de registro.
Pages/_Host.cshtml:
<body>
...
<script src="_framework/blazor.server.js" autostart="false"></script>
<script>
Blazor.start({
configureSignalR: function (builder) {
builder.configureLogging("information");
}
});
</script>
</body>
En el ejemplo anterior, information es equivalente a un nivel de registro de LogLevel.Information.
Para más información sobre el inicio de Blazor, vea Inicio de Blazor en ASP.NET Core.
Modificación del controlador de reconexión
Los eventos de conexión del circuito del controlador de reconexión pueden modificarse para obtener comportamientos personalizados, por ejemplo:
- Para notificar al usuario si la conexión se ha quitado.
- Para realizar el registro (desde el cliente) cuando un circuito está conectado.
Para modificar los eventos de conexión, registre las devoluciones de llamada para los siguientes cambios de conexión:
- Las conexiones que se quitan usan
onConnectionDown. - Las conexiones establecidas o restablecidas usan
onConnectionUp.
Es necesario especificar tanto onConnectionDown como onConnectionUp .
Pages/_Host.cshtml:
<body>
...
<script src="_framework/blazor.server.js" autostart="false"></script>
<script>
Blazor.start({
reconnectionHandler: {
onConnectionDown: (options, error) => console.error(error),
onConnectionUp: () => console.log("Up, up, and away!")
}
});
</script>
</body>
Para más información sobre el inicio de Blazor, vea Inicio de Blazor en ASP.NET Core.
Ajustar el número y el intervalo de reintentos de reconexión
Para ajustar el intervalo y el número de reintentos de reconexión, establezca el número de reintentos (maxRetries) y el período en milisegundos permitido en cada reintento (retryIntervalMilliseconds).
Pages/_Host.cshtml:
<body>
...
<script src="_framework/blazor.server.js" autostart="false"></script>
<script>
Blazor.start({
reconnectionOptions: {
maxRetries: 3,
retryIntervalMilliseconds: 2000
}
});
</script>
</body>
Para más información sobre el inicio de Blazor, vea Inicio de Blazor en ASP.NET Core.
Ocultar o reemplazar la pantalla de reconexión
Para ocultar la presentación de reconexión, establezca el valor _reconnectionDisplay del controlador de reconexión en un objeto vacío ({} o new Object()).
Pages/_Host.cshtml:
<body>
...
<script src="_framework/blazor.server.js" autostart="false"></script>
<script>
window.addEventListener('beforeunload', function () {
Blazor.defaultReconnectionHandler._reconnectionDisplay = {};
});
Blazor.start();
</script>
</body>
Para reemplazar la pantalla de reconexión, establezca _reconnectionDisplay del ejemplo anterior en el elemento que se va a mostrar:
Blazor.defaultReconnectionHandler._reconnectionDisplay =
document.getElementById("{ELEMENT ID}");
El marcador de posición {ELEMENT ID} es el identificador del elemento HTML que se va a mostrar.
Para más información sobre el inicio de Blazor, vea Inicio de Blazor en ASP.NET Core.
Personalice el retraso antes de que aparezca la pantalla de reconexión. Para ello, establezca la propiedad transition-delay en el CSS del sitio como elemento modal. En el siguiente ejemplo, el retraso de la transición se cambia de 500 ms (valor predeterminado) a 1000 ms (1 segundo).
wwwroot/css/site.css:
#components-reconnect-modal {
transition: visibility 0s linear 1000ms;
}
Desconexión del circuito Blazor del cliente
De forma predeterminada, un circuito Blazor se desconecta cuando se desencadena el evento de página unload. A fin de desconectar el circuito para otros escenarios en el cliente, invoque Blazor.disconnect en el controlador de eventos adecuado. En el ejemplo siguiente, el circuito se desconecta cuando la página está oculta (evento pagehide):
window.addEventListener('pagehide', () => {
Blazor.disconnect();
});
Para más información sobre el inicio de Blazor, vea Inicio de Blazor en ASP.NET Core.
Controlador de circuito de Blazor Server
Blazor Server permite que el código defina un controlador de circuito, que permite ejecutar el código en los cambios realizados en el estado del circuito de un usuario. Un controlador de circuito se implementa derivando de CircuitHandler y registrando la clase en el contenedor de servicios de la aplicación. El ejemplo siguiente de un controlador de circuito realiza un seguimiento de las conexiones abiertas de SignalR.
TrackingCircuitHandler.cs:
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.Server.Circuits;
public class TrackingCircuitHandler : CircuitHandler
{
private HashSet<Circuit> circuits = new();
public override Task OnConnectionUpAsync(Circuit circuit,
CancellationToken cancellationToken)
{
circuits.Add(circuit);
return Task.CompletedTask;
}
public override Task OnConnectionDownAsync(Circuit circuit,
CancellationToken cancellationToken)
{
circuits.Remove(circuit);
return Task.CompletedTask;
}
public int ConnectedCircuits => circuits.Count;
}
Los controladores de circuito se registran mediante DI. Las instancias con ámbito se crean por instancia de un circuito. Mediante el uso de TrackingCircuitHandler en el ejemplo anterior, se crea un servicio singleton porque se debe realizar un seguimiento del estado de todos los circuitos.
Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
...
services.AddSingleton<CircuitHandler, TrackingCircuitHandler>();
}
Si los métodos de un controlador de circuito personalizado producen una excepción no controlada, la excepción es grave para el circuito de Blazor Server. Para tolerar excepciones en el código de un controlador o en los métodos llamados, encapsule el código en una o varias instrucciones try-catch con control de errores y registro.
Cuando un circuito finaliza porque un usuario se ha desconectado y el marco está limpiando el estado del circuito, el marco desecha el ámbito de DI del circuito. Al desechar el ámbito, se eliminan también todos los servicios de DI con ámbito del circuito que implementan System.IDisposable. Si un servicio de DI produce una excepción no controlada durante la eliminación, el marco registra la excepción.
Azure SignalR Service
Se recomienda usar Azure SignalR Service ´con las aplicaciones Blazor Server hospedadas en Microsoft Azure. El servicio funciona junto con el centro Blazor de la aplicación para escalar verticalmente una aplicación Blazor Server a un gran número de conexiones de SignalR simultáneas. Además, los centros de datos de alto rendimiento y alcance global de SignalR Service son de gran ayuda a la hora de reducir la latencia ocasionada por la geografía. Para obtener compatibilidad con la representación previa con Azure SignalR Service, configure la aplicación para usar sesiones permanentes. Para obtener más información, vea Hospedaje e implementación de ASP.NET Core Blazor Server.
Recursos adicionales
- Introducción a ASP.NET Core SignalR
- Configuración de SignalR en ASP.NET Core
- Guía de mitigación de amenazas para ASP.NET Core Blazor Server
- Eventos de reconexión y de ciclo de vida de componentes de Blazor Server
- ¿Qué es Azure SignalR Service?
- Guía de rendimiento de Azure SignalR Service
- Publicar una aplicación ASP.NET Core SignalR para Azure App Service
En este artículo se explica cómo configurar y administrar conexiones de SignalR en aplicaciones Blazor.
Para obtener instrucciones generales sobre la configuración de SignalR para ASP.NET Core, consulte los temas del área Introducción a ASP.NET Core SignalR de la documentación. Para configurar SignalR agregado a una solución de Blazor WebAssembly hospedada, vea Configuración de SignalR en ASP.NET Core.
Negociación entre orígenes de SignalR para la autenticación
Para configurar el cliente subyacente de SignalR para que envíe credenciales, como cookies o encabezados de autenticación HTTP:
Use SetBrowserRequestCredentials para establecer Include en solicitudes de
fetchentre orígenes.IncludeRequestCredentialsMessageHandler.cs:using System.Net.Http; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Components.WebAssembly.Http; public class IncludeRequestCredentialsMessageHandler : DelegatingHandler { protected override Task<HttpResponseMessage> SendAsync( HttpRequestMessage request, CancellationToken cancellationToken) { request.SetBrowserRequestCredentials(BrowserRequestCredentials.Include); return base.SendAsync(request, cancellationToken); } }Si existe una conexión con un centro, asigne HttpMessageHandler a la opción HttpMessageHandlerFactory:
HubConnectionBuilder hubConnecton; ... hubConnecton = new HubConnectionBuilder() .WithUrl(new Uri(NavigationManager.ToAbsoluteUri("/chathub")), options => { options.HttpMessageHandlerFactory = innerHandler => new IncludeRequestCredentialsMessageHandler { InnerHandler = innerHandler }; }).Build();En el ejemplo anterior, la dirección URL de la conexión del centro se configura en el URI absoluto en
/chathub, que es la dirección URL que se usa en el tutorial de SignalR con Blazor en el componenteIndex(Pages/Index.razor). El URI también se puede establecer por medio de una cadena (por ejemplo,https://signalr.example.com) o mediante configuración.
Para obtener más información, vea Configuración de SignalR en ASP.NET Core.
Recursos adicionales
En este artículo se explica cómo configurar y administrar conexiones de SignalR en aplicaciones Blazor.
Para obtener instrucciones generales sobre la configuración de SignalR para ASP.NET Core, consulte los temas del área Introducción a ASP.NET Core SignalR de la documentación. Para configurar SignalR agregado a una solución de Blazor WebAssembly hospedada, vea Configuración de SignalR en ASP.NET Core.
Opciones de controlador de circuito
Configure el circuito Blazor Server con los valores de CircuitOptions que se muestran en la tabla siguiente.
| Opción | Valor predeterminado | Descripción |
|---|---|---|
| DetailedErrors | false |
Envío de mensajes de excepción detallados a JavaScript cuando se produce una excepción no controlada en el circuito o cuando una invocación de método de .NET a través de la interoperabilidad de JS produce una excepción. |
| DisconnectedCircuitMaxRetained | 100 | Número máximo de circuitos desconectados que el servidor contiene en la memoria cada vez. |
| DisconnectedCircuitRetentionPeriod | 3 minutos | Cantidad máxima de tiempo que un circuito desconectado se conserva en la memoria antes de desactivarlo. |
| JSInteropDefaultCallTimeout | 1 minuto | Cantidad máxima de tiempo que el servidor aguarda antes de agotar el tiempo de espera de invocación de una función de JavaScript asincrónica. |
| MaxBufferedUnacknowledgedRenderBatches | 10 | Número máximo de lotes de representación no confirmados por circuito que el servidor mantiene en la memoria en un momento dado para admitir una reconexión sólida. Después de alcanzar el límite, el servidor deja de generar nuevos lotes de representación hasta que el cliente confirme uno o varios lotes. |
Configure las opciones de Startup.ConfigureServices con un delegado de opciones en AddServerSideBlazor. En el siguiente ejemplo se asignan los valores de opción predeterminados que se muestran en la tabla anterior. Confirme que Startup.cs usa el espacio de nombres System (using System;).
Startup.ConfigureServices:
services.AddServerSideBlazor(options =>
{
options.DetailedErrors = false;
options.DisconnectedCircuitMaxRetained = 100;
options.DisconnectedCircuitRetentionPeriod = TimeSpan.FromMinutes(3);
options.JSInteropDefaultCallTimeout = TimeSpan.FromMinutes(1);
options.MaxBufferedUnacknowledgedRenderBatches = 10;
});
Para configurar HubConnectionContext, use HubConnectionContextOptions con AddHubOptions. Para obtener descripciones de las opciones, vea Configuración de SignalR en ASP.NET Core. En el siguiente ejemplo se asignan los valores de opción predeterminados. Confirme que Startup.cs usa el espacio de nombres System (using System;).
Startup.ConfigureServices:
services.AddServerSideBlazor()
.AddHubOptions(options =>
{
options.ClientTimeoutInterval = TimeSpan.FromSeconds(30);
options.EnableDetailedErrors = false;
options.HandshakeTimeout = TimeSpan.FromSeconds(15);
options.KeepAliveInterval = TimeSpan.FromSeconds(15);
options.MaximumParallelInvocationsPerClient = 1;
options.MaximumReceiveMessageSize = 32 * 1024;
options.StreamBufferCapacity = 10;
});
Blazor Configuración de la ruta del punto de conexión del centro
En Startup.Configure, las aplicaciones de Blazor Server llaman a MapBlazorHub en el objeto IEndpointRouteBuilder de UseEndpoints para asignar Blazor Hub a la ruta de acceso predeterminada de la aplicación. El script de Blazor Server (blazor.server.js) apunta automáticamente al punto de conexión creado por MapBlazorHub.
Reflejo del estado de la conexión en la interfaz de usuario
Cuando el cliente detecta que se ha perdido la conexión, se muestra al usuario una interfaz de usuario predeterminada mientras el cliente intenta volver a conectarse. Si se produce un error en la reconexión, se proporciona al usuario la opción de volver a intentarlo.
Para personalizar la interfaz de usuario, defina un elemento con un valor de id de components-reconnect-modal en el elemento <body> de la página _Host.cshtml de Razor.
Pages/_Host.cshtml:
<div id="components-reconnect-modal">
...
</div>
Agregue los siguientes estilos CSS a la hoja de estilos del sitio.
wwwroot/css/site.css:
#components-reconnect-modal {
display: none;
}
#components-reconnect-modal.components-reconnect-show {
display: block;
}
En la siguiente tabla se describen las clases de CSS que el marco Blazor aplica al elemento components-reconnect-modal.
| Clase de CSS | Indica… |
|---|---|
components-reconnect-show |
Una conexión perdida. El cliente intenta volver a conectarse. Se muestra el modal. |
components-reconnect-hide |
Se restablece una conexión activa con el servidor. Se oculta el modal. |
components-reconnect-failed |
Error de reconexión, probablemente debido a un error de la red. Para intentar la reconexión, llame a window.Blazor.reconnect() en JavaScript. |
components-reconnect-rejected |
Reconexión rechazada. Se ha alcanzado el servidor pero se ha rechazado la conexión y se ha perdido el estado del usuario en el servidor. Para volver a cargar la aplicación, llame a location.reload() en JavaScript. Este estado de conexión se puede producir cuando:
|
Modo de representación
De forma predeterminada, las aplicaciones Blazor Server realizan una representación previa de la interfaz de usuario en el servidor antes de que se establezca la conexión del cliente con él. Para más información, consulte Asistente de etiquetas de componente en ASP.NET Core.
Inicio de Blazor
Configure el inicio manual de un circuito de SignalR de la aplicación Blazor Server en el archivo Pages/_Host.cshtml:
- Agregue un atributo
autostart="false"a la etiqueta<script>para el scriptblazor.server.js. - Coloque un script que llame a
Blazor.startdespués de la etiqueta<script>del scriptblazor.server.jsy dentro de la etiqueta de cierre</body>.
Cuando autostart está deshabilitado, cualquier aspecto de la aplicación que no depende del circuito funciona normalmente. Por ejemplo, el enrutamiento del lado cliente está operativo. Sin embargo, cualquier aspecto que dependa del circuito no funcionará hasta que se llame a Blazor.start. El comportamiento de la aplicación es imprevisible sin ningún circuito establecido. Por ejemplo, los métodos de componente no se ejecutan mientras el circuito está desconectado.
Para más información, incluida la forma de inicializar Blazor cuando el documento está listo y de encadenar a Promise de JS, vea Inicio de Blazor en ASP.NET Core.
Configuración del registro de cliente de SignalR
En el generador de cliente, pase el objeto de configuración configureSignalR que llama a configureLogging con el nivel de registro.
Pages/_Host.cshtml:
<body>
...
<script src="_framework/blazor.server.js" autostart="false"></script>
<script>
Blazor.start({
configureSignalR: function (builder) {
builder.configureLogging("information");
}
});
</script>
</body>
En el ejemplo anterior, information es equivalente a un nivel de registro de LogLevel.Information.
Para más información sobre el inicio de Blazor, vea Inicio de Blazor en ASP.NET Core.
Modificación del controlador de reconexión
Los eventos de conexión del circuito del controlador de reconexión pueden modificarse para obtener comportamientos personalizados, por ejemplo:
- Para notificar al usuario si la conexión se ha quitado.
- Para realizar el registro (desde el cliente) cuando un circuito está conectado.
Para modificar los eventos de conexión, registre las devoluciones de llamada para los siguientes cambios de conexión:
- Las conexiones que se quitan usan
onConnectionDown. - Las conexiones establecidas o restablecidas usan
onConnectionUp.
Es necesario especificar tanto onConnectionDown como onConnectionUp .
Pages/_Host.cshtml:
<body>
...
<script src="_framework/blazor.server.js" autostart="false"></script>
<script>
Blazor.start({
reconnectionHandler: {
onConnectionDown: (options, error) => console.error(error),
onConnectionUp: () => console.log("Up, up, and away!")
}
});
</script>
</body>
Para más información sobre el inicio de Blazor, vea Inicio de Blazor en ASP.NET Core.
Ajustar el número y el intervalo de reintentos de reconexión
Para ajustar el intervalo y el número de reintentos de reconexión, establezca el número de reintentos (maxRetries) y el período en milisegundos permitido en cada reintento (retryIntervalMilliseconds).
Pages/_Host.cshtml:
<body>
...
<script src="_framework/blazor.server.js" autostart="false"></script>
<script>
Blazor.start({
reconnectionOptions: {
maxRetries: 3,
retryIntervalMilliseconds: 2000
}
});
</script>
</body>
Para más información sobre el inicio de Blazor, vea Inicio de Blazor en ASP.NET Core.
Ocultar o reemplazar la pantalla de reconexión
Para ocultar la presentación de reconexión, establezca el valor _reconnectionDisplay del controlador de reconexión en un objeto vacío ({} o new Object()).
Pages/_Host.cshtml:
<body>
...
<script src="_framework/blazor.server.js" autostart="false"></script>
<script>
window.addEventListener('beforeunload', function () {
Blazor.defaultReconnectionHandler._reconnectionDisplay = {};
});
Blazor.start();
</script>
</body>
Para reemplazar la pantalla de reconexión, establezca _reconnectionDisplay del ejemplo anterior en el elemento que se va a mostrar:
Blazor.defaultReconnectionHandler._reconnectionDisplay =
document.getElementById("{ELEMENT ID}");
El marcador de posición {ELEMENT ID} es el identificador del elemento HTML que se va a mostrar.
Para más información sobre el inicio de Blazor, vea Inicio de Blazor en ASP.NET Core.
Controlador de circuito de Blazor Server
Blazor Server permite que el código defina un controlador de circuito, que permite ejecutar el código en los cambios realizados en el estado del circuito de un usuario. Un controlador de circuito se implementa derivando de CircuitHandler y registrando la clase en el contenedor de servicios de la aplicación. El ejemplo siguiente de un controlador de circuito realiza un seguimiento de las conexiones abiertas de SignalR.
TrackingCircuitHandler.cs:
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.Server.Circuits;
public class TrackingCircuitHandler : CircuitHandler
{
private HashSet<Circuit> circuits = new HashSet<Circuit>();
public override Task OnConnectionUpAsync(Circuit circuit,
CancellationToken cancellationToken)
{
circuits.Add(circuit);
return Task.CompletedTask;
}
public override Task OnConnectionDownAsync(Circuit circuit,
CancellationToken cancellationToken)
{
circuits.Remove(circuit);
return Task.CompletedTask;
}
public int ConnectedCircuits => circuits.Count;
}
Los controladores de circuito se registran mediante DI. Las instancias con ámbito se crean por instancia de un circuito. Mediante el uso de TrackingCircuitHandler en el ejemplo anterior, se crea un servicio singleton porque se debe realizar un seguimiento del estado de todos los circuitos.
Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
...
services.AddSingleton<CircuitHandler, TrackingCircuitHandler>();
}
Si los métodos de un controlador de circuito personalizado producen una excepción no controlada, la excepción es grave para el circuito de Blazor Server. Para tolerar excepciones en el código de un controlador o en los métodos llamados, encapsule el código en una o varias instrucciones try-catch con control de errores y registro.
Cuando un circuito finaliza porque un usuario se ha desconectado y el marco está limpiando el estado del circuito, el marco desecha el ámbito de DI del circuito. Al desechar el ámbito, se eliminan también todos los servicios de DI con ámbito del circuito que implementan System.IDisposable. Si un servicio de DI produce una excepción no controlada durante la eliminación, el marco registra la excepción.
Azure SignalR Service
Se recomienda usar Azure SignalR Service ´con las aplicaciones Blazor Server hospedadas en Microsoft Azure. El servicio funciona junto con el centro Blazor de la aplicación para escalar verticalmente una aplicación Blazor Server a un gran número de conexiones de SignalR simultáneas. Además, los centros de datos de alto rendimiento y alcance global de SignalR Service son de gran ayuda a la hora de reducir la latencia ocasionada por la geografía. Para obtener compatibilidad con la representación previa con Azure SignalR Service, configure la aplicación para usar sesiones permanentes. Para obtener más información, vea Hospedaje e implementación de ASP.NET Core Blazor Server.
Recursos adicionales
- Introducción a ASP.NET Core SignalR
- Configuración de SignalR en ASP.NET Core
- Guía de mitigación de amenazas para ASP.NET Core Blazor Server
- Eventos de reconexión y de ciclo de vida de componentes de Blazor Server
- ¿Qué es Azure SignalR Service?
- Guía de rendimiento de Azure SignalR Service
- Publicar una aplicación ASP.NET Core SignalR para Azure App Service