net-core-30-Signalr-04-使用Redis做底板来支持横向扩展

27次阅读

共计 2805 个字符,预计需要花费 8 分钟才能阅读完成。

在实际的系统中,可能需要多台机器部署; 然而,Signalr 的连接信息是跟站点走的,举个例子
推送系统部署了 A、B 两个服务器,张三访问 A 服务器,李四访问 B 服务器,当张三通过 A 服务器向李四推送的时候,A 服务器上是找不到李四的连接信息的,自然也就推送不过了,这个时候就需要有一个统一协调的玩意,signalr 支持多种,Azure、Redis 等,本节以 Redis 作为底板,介绍如何在 Signalr 中使用 Redis 作为底板来支持横向扩展。

引入 Redis

  • 先引入 NuGet 包

Microsoft.AspNetCore.SignalR.StackExchangeRedis

  • 修改 Startup 中的 ConfigureServices 方法

    var appSection = Configuration.GetSection("App");
    services.Configure<AppSetting>(option => appSection.Bind(option));
    var appSetting = appSection.Get<AppSetting>();
    
    // 添加 Signalr
    services.AddSignalR(config =>
    {if (_webEnv.IsDevelopment())
        {config.EnableDetailedErrors = true;}
    })
    // 支持 MessagePack
    .AddMessagePackProtocol()
    // 使用 redis 做底板 支持横向扩展 Scale-out
    .AddStackExchangeRedis(o =>
      {
          o.ConnectionFactory = async writer =>
          {
              var config = new ConfigurationOptions
              {
                  AbortOnConnectFail = false,
                  ChannelPrefix = "__signalr_",
              };
              config.DefaultDatabase = appSetting.SignalrRedisCache.DatabaseId;
              var connection = await ConnectionMultiplexer.ConnectAsync(appSetting.SignalrRedisCache.ConnectionString, writer);
              connection.ConnectionFailed += (_, e) =>
              {Console.WriteLine("Connection to Redis failed.");
              };
    
              if (connection.IsConnected)
              {Console.WriteLine("connected to Redis.");
              }
              else
              {Console.WriteLine("Did not connect to Redis");
              }
    
              return connection;
          };
      });

可以自定义 Redis 相关配置,此处的 appSetting 为已经定义好的配置实体,包括了,主要配置、CROS 配置、Jwt 配置、redis 配置等详情如下

/// <summary>
/// 对应 appsettings 中的 App 节点的配置信息
/// </summary>
public class AppSetting
{public JwtSetting JwtSetting { set;get;}
    public RedisCache RedisCache {set;get;}
    public RedisCache SignalrRedisCache {set; get;}
    public string CORS {set;get;}
    /// <summary>
    /// 是否主站点 (用于运行清理任务等)
    /// </summary>
    public bool MainSite {set;get;}
}

/// <summary>
/// JWT 设置
/// </summary>
public class JwtSetting
{
    /// <summary>
    /// 发行者 表示 token 是谁颁发的
    /// </summary>
    public string Issuer {set; get;}
    /// <summary>
    /// 表示哪些客户端可以使用这个 token
    /// </summary>
    public string Audience {set; get;}
    /// <summary>
    /// 加密的 Key 必须大于 16 位
    /// </summary>
    public string SecretKey {set; get;}
}

public class RedisCache
{public string ConnectionString { set;get;}
    public int DatabaseId {set; get;}
}

对应的配置文件如下

{
"Logging": {
  "LogLevel": {
    "Default": "Debug",
    "System": "Information",
    "Microsoft": "Information",
    "Microsoft.AspNetCore.SignalR": "Trace",
    "Microsoft.AspNetCore.Http.Connections": "Trace"
  }
},
"App": {
  "RedisCache": {
    "ConnectionString": "127.0.0.1:6379,password=#####,ssl=false,abortConnect=true,connectTimeout=5000",
    "DatabaseId": 10
  },
  "SignalrRedisCache": {
    "ConnectionString": "127.0.0.1:6379,password=#####,ssl=false,abortConnect=true,connectTimeout=5000",
    "DatabaseId": 10
  },
  "CORS": "https://localhost:60000,http://localhost:60001",
  "MainSite": true,
  "JwtSetting": {
    "Issuer": "http://localhost:50000", // 颁发者
    "Audience": "http://localhost:50000", // 使用者
    "SecretKey": "Wetrial20196666666" // key 大于 16 位
  }
}
}

首先,将配置文件跟实体对象映射,下次在其他地方使用的时候可以直接通过 DI 注入,然后通过 AddStackExchangeRedis 配置使用 redis 作为底板

更多内容请通过快速导航查看下一篇

快速导航

标题 内容
索引 .net core 3.0 Signalr – 实现一个业务推送系统
上一篇 .net core 3.0 Signalr – 03 使用 MessagePack 压缩传输内容
下一篇 .net core 3.0 Signalr – 05 使用 jwt 将用户跟 signalr 关联
源码地址 源码
官方文档 官方文档

正文完
 0