获取连接到SignalR集线器的侦听器,客户端的数量

Sha*_*eKm 47 c# asp.net asp.net-mvc-3 signalr signalr-hub

有没有办法找出侦听器的数量(连接到集线器的客户端?)

如果至少连接了一个客户端,我正在尝试运行/启动任务,否则不启动它:

[HubName("taskActionStatus")]
public class TaskActionStatus : Hub, IDisconnect
{
    static CancellationTokenSource tokenSource;

    public void GetTasksStatus(int? siteId)
    {
        tokenSource = new CancellationTokenSource();
        CancellationToken ct = tokenSource.Token;

        ITaskRepository taskRepository = UnityContainerSetup.Container.Resolve<ITaskRepository>();

        // init task for checking task statuses
        var tasksItem = new DownloadTaskItem();
        taskRepository.GetTasksStatusAsync(siteId, tasksItem, ct);

        // subscribe to event [ listener ]
        tasksItem.Changed += new EventHandler<TaskEventArgs>(UpdateTasksStatus);
    }

    public void UpdateTasksStatus(object sender, TaskEventArgs e)
    {
        Clients.updateMessages(e.Tasks);
    }

    // when browsing away from page
    public Task Disconnect()
    {
        try
        {
            tokenSource.Cancel();
        }
        catch (Exception)
        {
            //
        }

        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

谢谢

And*_*rpi 84

没有办法从SignalR那里得到这个数.您必须使用Hub上的OnConnect()OnDisconnect()方法来自行计算.

使用静态类来保存计数的简单示例:

public static class UserHandler
{
    public static HashSet<string> ConnectedIds = new HashSet<string>();
}

public class MyHub : Hub
{
    public override Task OnConnected()
    {
        UserHandler.ConnectedIds.Add(Context.ConnectionId);
        return base.OnConnected();
    }

    public override Task OnDisconnected()
    {
        UserHandler.ConnectedIds.Remove(Context.ConnectionId);
        return base.OnDisconnected();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你从中获得计数UserHandler.ConnectedIds.Count.

  • 如果您只是要运行一台服务器,那么使用像这样的静态类可以正常工作,但如果您在云中并且在多台服务器之间使用负载均衡器,则此解决方案会崩溃.但是,您可以使用缓存服务器来存储连接的用户.我们使用Azure中托管的Redis. (12认同)
  • +1只记得在app域重启时该对象将被重置; 你应该考虑在某个时候坚持这个对象; 每当有人添加或删除时,我通常会这样做. (6认同)
  • 不要忘记在SignalR 2.2.1中覆盖OnReconnected.如果客户端重新连接相同的connection_id,则不会调用OnConnect. (5认同)
  • `static HashSet&lt;string&gt; ConnectedIds` 似乎根本不是线程安全的。 (2认同)

Ogg*_*las 28

对于版本2.1.1+,它应该是:

public static class UserHandler
{
    public static HashSet<string> ConnectedIds = new HashSet<string>();
}

public class MyHub : Hub
{
    public override Task OnConnected()
    {
        UserHandler.ConnectedIds.Add(Context.ConnectionId);
        return base.OnConnected();
    }

    public override Task OnDisconnected(bool stopCalled)
    {
        UserHandler.ConnectedIds.Remove(Context.ConnectionId);
        return base.OnDisconnected(stopCalled);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 在服务器分片的情况下要小心.喜欢使用Cache或Db来存储你的慢跑. (2认同)
  • 据我所知,HasSet 不是线程安全的,因此我认为我们需要在这种方法中进行一些同步,同时访问 ConnectedIds (2认同)

Лоп*_*ная 7

在 SIGnalR(2.4.1 版)中,这很容易:

public int GetOnline()
{
   return GlobalHost.DependencyResolver.Resolve<ITransportHeartbeat>().GetConnections().Count;
}
Run Code Online (Sandbox Code Playgroud)

只需从客户端调用此方法(:


ejd*_*313 5

现在您需要:

public override Task OnConnectedAsync()
    {
        UserHandler.ConnectedIds.Add(Context.ConnectionId);

        return base.OnConnectedAsync();
    }

    public override Task OnDisconnectedAsync(Exception exception)
    {
        UserHandler.ConnectedIds.Remove(Context.ConnectionId);
        return base.OnDisconnectedAsync(exception);
    }
Run Code Online (Sandbox Code Playgroud)

  • 恕我直言,也许您应该编辑已接受的答案而不是添加新答案?保持线索清晰,减少答案。此外,人们更有可能获得第一个(在本例中是被接受的)答案。 (2认同)