C# 使用SQL背板扩展信号器并维护服务器之间的用户列表

C# 使用SQL背板扩展信号器并维护服务器之间的用户列表,c#,sql,signalr,signalr-backplane,C#,Sql,Signalr,Signalr Backplane,我希望有人已经遇到了这一点,或者至少可以发现我的代码有什么问题 我已经使用MVC和SignalR创建了一个基于浏览器的聊天应用程序,因为我需要一个用户登录聊天。我已经针对MVC控制器实现了一个注册,它将用户添加到内部用户列表中 public static void Register(string userName, string userRole, string userBase, string userLocation) { var userInfo = (from user in U

我希望有人已经遇到了这一点,或者至少可以发现我的代码有什么问题

我已经使用MVC和SignalR创建了一个基于浏览器的聊天应用程序,因为我需要一个用户登录聊天。我已经针对MVC控制器实现了一个注册,它将用户添加到内部用户列表中

public static void Register(string userName, string userRole, string userBase, string userLocation)
{
    var userInfo = (from user in UsersList where user.Name == userName select user).FirstOrDefault();
    if (userInfo != null)
    {
        userInfo.Location = userLocation;
        userInfo.Role = userRole;
        userInfo.Base = userBase;
        return;
    }

    var rgx = new Regex("[^a-zA-Z0-9 -]");
    UsersList.Add(
        new UserInfo
        {
            Name = userName,
            NameId = rgx.Replace(userName, "").Replace(" ", ""),
            Base = userBase,
            Location = userLocation,
            Role = userRole,
            Group = "Cleo",
            Container = userLocation,
            ContainerId = rgx.Replace(userLocation, "").Replace(" ", "").Trim()
        });
}
在客户端,我实例化了
chatHub
,然后调用
Connect

$(function () {
    var objHub = $.connection.chatHub;
    loadClientMethods(objHub);
    $.connection.hub.start().done(function () {
        loadEvents(objHub);
    });

function loadEvents(objHub) {
    $('#hState').val('open');
    objHub.server.connect(gloalUserNameId);
}
所有这些在一台服务器上运行良好,并且所有连接都保存在内存中,顺便说一句,这已经投入生产一年多了

现在,我需要为我们的聊天应用程序建立更好的弹性,例如在负载平衡的环境中,但由于所有内容都在内存中,我立即遇到了用户a连接到服务器X和用户B连接到服务器Y的问题(两者都看不到对方,您可以看到问题)

因此,在网上花了好几个小时,我发现了几篇关于使用Redis或SQL扩展Signaler的文章。因为我们公司使用SQL,并且在这方面有很多经验,所以我选择了它

我包括了nuget包,并将我的
启动
类修改为

string connectionString = "Server=.;Trusted_Connection=True;Database=CleoChatHost;";
GlobalHost.DependencyResolver.UseSqlServer(connectionString);
app.MapSignalR();
我在IIS中分别在不同的端口上配置了两个网站,以模拟负载平衡环境进行测试,例如,我将其称为SiteA和SiteB

当我运行每个站点时,会发生以下情况:

  • 使用?用户名=TestUserA启动SiteA,然后使用?用户名=TestUserB启动SiteB --结果是SiteA加载(最初没有联系人),然后SiteB加载,SiteA用户列表用TestUserB更新。SiteB没有用户
注:执行与上述相反的操作会得到相同的结果

我不知道问题是什么,我已经检查了SQL数据库,可以看到背板已经创建了SQL表,数据正在进入其中。我也尝试过用与上面相同的问题实现Redis解决方案

是否有人实施了这一点,并遇到了相同的问题?或者有人能解释一下这个问题是什么吗

编辑 经过进一步诊断/测试后,问题似乎与每个服务器上维护的内部
UserList
有关,我认为事件顺序如下:

  • UserA
    登录到
    SiteA
  • SiteA
    UserA
    添加到
    SiteA
  • SiteA
    从客户端执行
    hub.Connect(…)
    ,客户端依次执行
    Clients.client(…).DrawTree(…)
    Clients.AllExcept(…).addUser(…)
  • 前面的调用将更新
    SiteA
    用户列表,并通知所有连接的客户端新用户
  • SiteA
    已连接且没有活动用户
  • UserB
    登录到
    SiteB
  • SiteB
    SiteB
  • SiteB
    从客户端执行
    hub.Connect(…)
    ,客户端依次执行
    Clients.client(…).DrawTree(…)
    Clients.AllExcept(…).addUser(…)
  • 前面的调用将更新
    SiteB
    用户列表,并通知所有连接的客户端新用户 --这将在
    SiteA
    客户端上执行
    addUser
    ,以将
    UserB
    添加到用户列表中
  • SiteB
    已连接且没有活动用户,而
    SiteA
    有一个活动用户
我认为问题在于,SQL背板只会在消息发送时处理消息,并且已经从SQL数据库中表的命名约定中确认了这一点。但是,内部
用户列表
在负载平衡的服务器之间不同步。
SiteA
更新为
UserB
这一事实只是因为
UserB
连接到
SiteB
时播放了
addUser
(意思是
SiteB
仅包含
UserB
,而
SiteA
仅包含
UserA


为了更新我上面的问题,我将如何在服务器之间维护
UserList
?我会使用SQL背板来实现这一点吗?

您是否找到了实现这一点的方法?我们也有类似的问题,看我的问题,你有没有发现如何使这项工作?我们也有类似的问题,请看我的问题