Configuración de un backplane de Redis para ASP.NET Core SignalR escalado horizontal

Por Andrew Andrew Andrewton-Nurse, Brady Gastery Tom Dykstra,

En este artículo se explican aspectos específicos de la configuración de un servidor de Redis que se usará para SignalR escalar horizontalmente una ASP.NET Core SignalR aplicación.

Configuración de un backplane de Redis

  • Implementar un servidor de Redis.

    Importante

    Para su uso en producción, solo se recomienda un backplane de Redis cuando se ejecuta en el mismo centro de datos que la SignalR aplicación. De lo contrario, la latencia de red degrada el rendimiento. Si la SignalR aplicación se ejecuta en la nube de Azure, se recomienda el servicio de Azure en lugar de un plano posterior de SignalR Redis.

    Para obtener más información, consulte los siguientes recursos:

  • En la SignalR aplicación, instale el Microsoft.AspNetCore.SignalR.Redis NuGet paquete.

  • En el Startup.ConfigureServices método , llame a después de AddRedis AddSignalR :

    services.AddSignalR().AddRedis("<your_Redis_connection_string>");
    
  • Configure las opciones según sea necesario:

    La mayoría de las opciones se pueden establecer en la cadena de conexión o en el objeto ConfigurationOptions. Las opciones especificadas en ConfigurationOptions invalidan las establecidas en la cadena de conexión.

    En el ejemplo siguiente se muestra cómo establecer opciones en el ConfigurationOptions objeto . En este ejemplo se agrega un prefijo de canal para que varias aplicaciones puedan compartir la misma instancia de Redis, como se explica en el paso siguiente.

    services.AddSignalR()
      .AddRedis(connectionString, options => {
          options.Configuration.ChannelPrefix = "MyApp";
      });
    

    En el código anterior, options.Configuration se inicializa con lo que se especificó en la cadena de conexión.

  • En la SignalR aplicación, instale uno de los siguientes paquetes NuGet aplicación:

    • Microsoft.AspNetCore.SignalR.StackExchangeRedis - Depende de StackExchange.Redis 2.X.X. Este es el paquete recomendado para ASP.NET Core 2.2 y versiones posteriores.
    • Microsoft.AspNetCore.SignalR.Redis - Depende de StackExchange.Redis 1.X.X. Este paquete no se incluye en ASP.NET Core 3.0 y versiones posteriores.
  • En el Startup.ConfigureServices método , llame a AddStackExchangeRedis :

    services.AddSignalR().AddStackExchangeRedis("<your_Redis_connection_string>");
    

Al usar Microsoft.AspNetCore.SignalR.Redis , llame a AddRedis .

  • Configure las opciones según sea necesario:

    La mayoría de las opciones se pueden establecer en la cadena de conexión o en el objeto ConfigurationOptions. Las opciones especificadas en ConfigurationOptions invalidan las establecidas en la cadena de conexión.

    En el ejemplo siguiente se muestra cómo establecer opciones en el ConfigurationOptions objeto . En este ejemplo se agrega un prefijo de canal para que varias aplicaciones puedan compartir la misma instancia de Redis, como se explica en el paso siguiente.

    services.AddSignalR()
      .AddStackExchangeRedis(connectionString, options => {
          options.Configuration.ChannelPrefix = "MyApp";
      });
    

Al usar Microsoft.AspNetCore.SignalR.Redis , llame a AddRedis .

En el código anterior, options.Configuration se inicializa con lo que se especificó en la cadena de conexión.

Para obtener información sobre las opciones de Redis, consulte la documentación de StackExchange Redis.

  • En la SignalR aplicación, instale el siguiente NuGet paquete:

    • Microsoft.AspNetCore.SignalR.StackExchangeRedis
  • En el Startup.ConfigureServices método , llame a AddStackExchangeRedis :

    services.AddSignalR().AddStackExchangeRedis("<your_Redis_connection_string>");
    
  • Configure las opciones según sea necesario:

    La mayoría de las opciones se pueden establecer en la cadena de conexión o en el objeto ConfigurationOptions. Las opciones especificadas en ConfigurationOptions invalidan las establecidas en la cadena de conexión.

    En el ejemplo siguiente se muestra cómo establecer opciones en el ConfigurationOptions objeto . En este ejemplo se agrega un prefijo de canal para que varias aplicaciones puedan compartir la misma instancia de Redis, como se explica en el paso siguiente.

    services.AddSignalR()
      .AddStackExchangeRedis(connectionString, options => {
          options.Configuration.ChannelPrefix = "MyApp";
      });
    

    En el código anterior, options.Configuration se inicializa con lo que se especificó en la cadena de conexión.

    Para obtener información sobre las opciones de Redis, consulte la documentación de StackExchange Redis.

  • Si usa un servidor de Redis para varias SignalR aplicaciones, use un prefijo de canal diferente para cada SignalR aplicación.

    Al establecer un prefijo de canal, se SignalR aísla una aplicación de otras que usan prefijos de canal diferentes. Si no asigna prefijos diferentes, un mensaje enviado desde una aplicación a todos sus propios clientes irá a todos los clientes de todas las aplicaciones que usan el servidor redis como un backplane.

  • Configure el software de equilibrio de carga de la granja de servidores para sesiones permanentes. Estos son algunos ejemplos de documentación sobre cómo hacerlo:

Errores del servidor redis

Cuando un servidor de Redis se queda sin servicio, produce excepciones que indican que los SignalR mensajes no se entregarán. Algunos mensajes de excepción típicos:

  • Error al escribir el mensaje
  • No se pudo invocar el método central 'MethodName'
  • Error de conexión a Redis

SignalR no almacena en búfer los mensajes para enviarlos cuando el servidor vuelva a crearse. Se pierden los mensajes enviados mientras el servidor de Redis está sin servicio.

SignalR se vuelve a conectar automáticamente cuando el servidor de Redis está disponible de nuevo.

Comportamiento personalizado para errores de conexión

Este es un ejemplo que muestra cómo controlar los eventos de error de conexión de Redis.

services.AddSignalR()
        .AddRedis(o =>
        {
            o.ConnectionFactory = async writer =>
            {
                var config = new ConfigurationOptions
                {
                    AbortOnConnectFail = false
                };
                config.EndPoints.Add(IPAddress.Loopback, 0);
                config.SetDefaultPorts();
                var connection = await ConnectionMultiplexer.ConnectAsync(config, writer);
                connection.ConnectionFailed += (_, e) =>
                {
                    Console.WriteLine("Connection to Redis failed.");
                };

                if (!connection.IsConnected)
                {
                    Console.WriteLine("Did not connect to Redis.");
                }

                return connection;
            };
        });
services.AddSignalR()
        .AddMessagePackProtocol()
        .AddStackExchangeRedis(o =>
        {
            o.ConnectionFactory = async writer =>
            {
                var config = new ConfigurationOptions
                {
                    AbortOnConnectFail = false
                };
                config.EndPoints.Add(IPAddress.Loopback, 0);
                config.SetDefaultPorts();
                var connection = await ConnectionMultiplexer.ConnectAsync(config, writer);
                connection.ConnectionFailed += (_, e) =>
                {
                    Console.WriteLine("Connection to Redis failed.");
                };

                if (!connection.IsConnected)
                {
                    Console.WriteLine("Did not connect to Redis.");
                }

                return connection;
            };
        });

Agrupación en clústeres de Redis

La agrupación en clústeres de Redis es un método para lograr una alta disponibilidad mediante el uso de varios servidores de Redis. La agrupación en clústeres no se admite oficialmente, pero puede funcionar.

Pasos siguientes

Para obtener más información, consulte los siguientes recursos: