【问题标题】:Finding Connection by UserId in SignalR在 SignalR 中按 UserId 查找连接
【发布时间】:2012-11-10 17:42:29
【问题描述】:

我有一个网页,它使用 ajax 轮询从服务器获取股市更新。我想改用 SignalR,但我无法理解它如何/是否会起作用。

好吧,这不是真正的股市更新,但类比有效。

我见过的 SignalR 示例向当前连接、所有连接或组发送消息。在我的示例中,库存更新发生在当前连接之外,因此没有“当前连接”之类的东西。并且用户的帐户与一些股票相关联,因此向所有连接或组发送股票通知也不起作用。 我需要能够找到与某个 userId 关联的连接。

这是一个假代码示例:

foreach(var stock in StockService.GetStocksWithBigNews())
{
    var userIds = UserService.GetUserIdsThatCareAboutStock(stock);

    var connections = /* find connections associated with user ids */;

    foreach(var connection in connections)
    {
        connection.Send(...);
    }
}

In this question on filtering connections,他们提到我可以将当​​前连接保留在内存中,但 (1) 这不利于扩展,(2) 这不利于多节点网站。这两点对我们当前的应用程序都至关重要。这让我觉得我必须向所有节点发送消息才能找到连接到每个节点的用户>>我的大脑在混乱中爆炸。

问题

如何为特定用户找到可扩展的连接?我是不是想错了?

【问题讨论】:

    标签: c# asp.net signalr


    【解决方案1】:

    我昨晚创建了一个小项目来学习这个。我使用了 1.0 alpha,它是直截了当的。我创建了一个 Hub 并从那里开始工作:)

    我的项目有 N 个计算单元(一些服务器处理工作),当它们启动时,它们会调用 ComputeUnitRegister。

    await HubProxy.Invoke("ComputeUnitReqisted", _ComputeGuid);
    

    每次他们做某事时他们都会打电话

    HubProxy.Invoke("Running", _ComputeGuid);
    

    HubProxy 在哪里:

    HubConnection Hub = new HubConnection(RoleEnvironment.IsAvailable ?
                        RoleEnvironment.GetConfigurationSettingValue("SignalREndPoint"):
                        "http://taskqueue.cloudapp.net/");
    IHubProxy HubProxy = Hub.CreateHubProxy("ComputeUnits"); 
    

    我使用 RoleEnviroment.IsAvailable 是因为我现在可以将其作为 Azure Role、控制台应用程序或 .NET 4.5 中的任何内容运行。 Hub 被放置在一个 MVC4 网站项目中,并像这样启动:

            GlobalHost.Configuration.ConnectionTimeout = TimeSpan.FromSeconds(50);
            RouteTable.Routes.MapHubs();
    
    public class ComputeUnits : Hub
    {
         public Task Running(Guid MyGuid)
         {
             return Clients.Group(MyGuid.ToString()).ComputeUnitHeartBeat(MyGuid,
                    DateTime.UtcNow.ToEpochMilliseconds());            
         }
         public Task ComputeUnitReqister(Guid MyGuid)
         {
             Groups.Add(Context.ConnectionId, "ComputeUnits").Wait(); 
             return Clients.Others.ComputeUnitCameOnline(new { Guid = MyGuid,
                    HeartBeat = DateTime.UtcNow.ToEpochMilliseconds() });           
         }
         public void SubscribeToHeartBeats(Guid MyGuid)
         {
             Groups.Add(Context.ConnectionId, MyGuid.ToString());
         }
    }
    

    我的客户是 Javascript 客户,它们有方法(如果您还需要查看此代码,请告诉我)。但基本上他们监听ComputeUnitCameOnline,当它运行时他们调用服务器SubscribeToHeartBeats。这意味着无论何时服务器计算单元正在执行某些工作,它都会调用 Running,这将在 JavaScript 客户端上触发 ComputeUnitHeartBeat

    我希望您可以使用它来了解如何使用组和连接。最后,它还通过添加几行代码来扩展多个 azure 角色:

        GlobalHost.HubPipeline.EnableAutoRejoiningGroups();
        GlobalHost.DependencyResolver.UseServiceBus(
            serviceBusConnectionString,
            2,
            3,
            GetRoleInstanceNumber(),
              topicPathPrefix /* the prefix applied to the name of each topic used */
            );
    

    您可以在 azure 上获取服务总线上的连接字符串,记住 Provider=SharedSecret。但是在添加 nuget 打包时,连接字符串语法也会粘贴到您的 web.config 中。 2 是要拆分多少个主题。主题可以包含 1Gb 的数据,因此您可以根据性能增加它。 3 是拆分它的节点数。我使用了 3,因为我有 2 个 Azure 实例和我的本地主机。您可以像这样获得 RoleNumber(请注意,我将 localhost 硬编码为 2)。

    private static int GetRoleInstanceNumber()
    {
        if (!RoleEnvironment.IsAvailable)
            return 2;
    
        var roleInstanceId = RoleEnvironment.CurrentRoleInstance.Id;
        var li1 = roleInstanceId.LastIndexOf(".");
        var li2 = roleInstanceId.LastIndexOf("_");
        var roleInstanceNo = roleInstanceId.Substring(Math.Max(li1, li2) + 1);
        return Int32.Parse(roleInstanceNo);
    }
    

    你可以在http://taskqueue.cloudapp.net/#/compute-units看到这一切。

    【讨论】:

    • 我们已经简化了很多,很快就会发布一个 nuget 包。感谢这篇精彩的文章!
    • 我发现它很简单,想知道什么变得更简单:)
    【解决方案2】:

    使用 SignalR 时,在客户端连接到服务器后,会为他们提供一个连接 ID(这对于提供实时通信至关重要)。是的,它存储在内存中,但 SignalR 也可以在多节点环境中使用。例如,您可以使用 Redis 甚至 Sql Server 背板(更多内容)。长话短说,我们通过背板/服务总线为您处理横向扩展方案,您无需担心。

    【讨论】:

    • 感谢 Taylor - 这清楚地表明 SignalR 应该可以工作。关于如何实现它的任何提示?我仍然不太清楚如何将 SqlServer 与 SignalR 一起使用或如何找到连接。
    • 我提供了一个我昨晚所做的样本,都是泰勒所说的,只是详细解释了。
    猜你喜欢
    • 2016-01-25
    • 1970-01-01
    • 2013-04-16
    • 2021-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多