【问题标题】:How can I get object fill by SignalR Method?如何通过 SignalR 方法获得对象填充?
【发布时间】:2019-11-12 00:06:05
【问题描述】:

这是我的问题:

我想从控制器调用 signalR 函数来获取连接的用户列表。 在我的 OnConnected()、OnDisconnected 方法中,我收集了正确的数据,但是当我创建自己的方法时,我无法获取用户列表。

我觉得我的上下文有问题,因为我的列表是空的,但我不知道为什么。

我已经尝试了一些测试:

这是在我的应用程序中使用 SignalR 连接的用户数计数器。 用户列表使用 OnConnected() 方法填充并使用 OnDisconnected() 清理

OnConnected() 一个用户被添加:

public override async Task OnConnected()
        {
            var currentCollab = Context.User.Identity.Name.Length > 0 ? Context.User.Identity.Name : "";
            var module = Context.QueryString["module"];

            if (!string.IsNullOrEmpty(module))
            {
                SignalRUsers.Add(new UserConnected()
                {
                    ConnectionId = Context.ConnectionId,
                    UserName = currentCollab,
                    ModuleActif = module
                });
            }


            await Clients.All.UpdateCountAccueil(SignalRUsers.Count(x => x.ModuleActif.ToUpper().Equals(ModuleName.Accueil.Value)), SignalRUsers.Where(x => x.ModuleActif.ToUpper().Equals(ModuleName.Accueil.Value)));

            await base.OnConnected();
        }

在此方法SignalRUsers 中,列表中填充了所有以前的连接,但是一旦我尝试在我的控制器中调用它的方法中从该列表中检索值,该列表就完全为空(虽然有许多活动连接)

完成Hub类:


using System;
using System.Activities.Statements;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.Util;
using System.Windows.Forms;
using ConvergenceCore.ServiceSettingsManager;
using ConvergenceDataAccess.ActiveDirectory;
using Microsoft.AspNet.SignalR;

namespace Main
{

    public class ChatHub : Hub
    {
        private static long counterAccueil = 0;
        private static long counterParam = 0;


        static Dictionary<string, int> CurrentConnections = new Dictionary<string, int>();
        static List<UserConnected> SignalRUsers = new List<UserConnected>();


        public void Send(string module, string etat, string message)
        {

            // Call the broadcastMessage method to update clients.
            Clients.All.broadcastMessage(module, etat, message);
        }


        public override async Task OnReconnected()
        {

            var currentCollab = Context.User.Identity.Name.Length > 0 ? Context.User.Identity.Name : "";
            var module = Context.QueryString["module"];

            if (!string.IsNullOrEmpty(module))
            {
                SignalRUsers.Add(new UserConnected()
                {
                    ConnectionId = Context.ConnectionId,
                    UserName = currentCollab,
                    ModuleActif = module
                });
            }

            await Clients.All.UpdateCountAccueil(SignalRUsers.Count(x => x.ModuleActif.ToUpper().Equals(ModuleName.Accueil.Value)), SignalRUsers.Where(x => x.ModuleActif.ToUpper().Equals(ModuleName.Accueil.Value)));
            await Clients.All.UpdateCountParam(SignalRUsers.Count(x => x.ModuleActif.ToUpper().Equals(ModuleName.Param.Value)), SignalRUsers.Where(x => x.ModuleActif.ToUpper().Equals(ModuleName.Param.Value)));
            await Clients.All.UpdateCountRh(SignalRUsers.Count(x => x.ModuleActif.ToUpper().Equals(ModuleName.Rh.Value)), SignalRUsers.Where(x => x.ModuleActif.ToUpper().Equals(ModuleName.Rh.Value)));
            await Clients.All.UpdateCountFacturation(SignalRUsers.Count(x => x.ModuleActif.ToUpper().Equals(ModuleName.Facturation.Value)), SignalRUsers.Where(x => x.ModuleActif.ToUpper().Equals(ModuleName.Facturation.Value)));


            await base.OnReconnected();
        }

        public override async Task OnConnected()
        {
            var currentCollab = Context.User.Identity.Name.Length > 0 ? Context.User.Identity.Name : "";
            var module = Context.QueryString["module"];

            if (!string.IsNullOrEmpty(module))
            {
                SignalRUsers.Add(new UserConnected()
                {
                    ConnectionId = Context.ConnectionId,
                    UserName = currentCollab,
                    ModuleActif = module
                });
            }


            await Clients.All.UpdateCountAccueil(SignalRUsers.Count(x => x.ModuleActif.ToUpper().Equals(ModuleName.Accueil.Value)), SignalRUsers.Where(x => x.ModuleActif.ToUpper().Equals(ModuleName.Accueil.Value)));
            await Clients.All.UpdateCountParam(SignalRUsers.Count(x => x.ModuleActif.ToUpper().Equals(ModuleName.Param.Value)), SignalRUsers.Where(x => x.ModuleActif.ToUpper().Equals(ModuleName.Param.Value)));
            await Clients.All.UpdateCountRh(SignalRUsers.Count(x => x.ModuleActif.ToUpper().Equals(ModuleName.Rh.Value)), SignalRUsers.Where(x => x.ModuleActif.ToUpper().Equals(ModuleName.Rh.Value)));
            await Clients.All.UpdateCountFacturation(SignalRUsers.Count(x => x.ModuleActif.ToUpper().Equals(ModuleName.Facturation.Value)), SignalRUsers.Where(x => x.ModuleActif.ToUpper().Equals(ModuleName.Facturation.Value)));

            await base.OnConnected();
        }

        public override async Task OnDisconnected(bool stopCalled)
        {
            var userToDelete = SignalRUsers.FirstOrDefault(x => x.ConnectionId == Context.ConnectionId);
            SignalRUsers.Remove(userToDelete);
            //CurrentConnections.Remove(module + Context.ConnectionId);

            await Clients.All.UpdateCountAccueil(SignalRUsers.Count(x => x.ModuleActif.ToUpper().Equals(ModuleName.Accueil.Value)), SignalRUsers.Where(x => x.ModuleActif.ToUpper().Equals(ModuleName.Accueil.Value)));
            await Clients.All.UpdateCountParam(SignalRUsers.Count(x => x.ModuleActif.ToUpper().Equals(ModuleName.Param.Value)), SignalRUsers.Where(x => x.ModuleActif.ToUpper().Equals(ModuleName.Param.Value)));
            await Clients.All.UpdateCountRh(SignalRUsers.Count(x => x.ModuleActif.ToUpper().Equals(ModuleName.Rh.Value)), SignalRUsers.Where(x => x.ModuleActif.ToUpper().Equals(ModuleName.Rh.Value)));
            await Clients.All.UpdateCountFacturation(SignalRUsers.Count(x => x.ModuleActif.ToUpper().Equals(ModuleName.Facturation.Value)), SignalRUsers.Where(x => x.ModuleActif.ToUpper().Equals(ModuleName.Facturation.Value)));

            await base.OnDisconnected(stopCalled);

        }

        public List<UserConnected> GetListUsersConnected(string module)
        {
            return SignalRUsers.Where(x => x.ModuleActif == module).ToList();
        }
    }

    public class UserConnected
    {
        public string UserName { get; set; }
        public string ConnectionId { get; set; }
        public string ModuleActif { get; set; }

    }
}

在我的 控制器中:

 public PartialViewResult DetailUsersConnected(string module)
        {
           ChatHub hub = new ChatHub();
           var listUsers = hub.GetListUsersConnected(module);

            return PartialView("../Parametrages/Content/_DetailsUserConnected", listUsers);
        }

为什么我的 GetListUsersConnected 方法中的列表为空?

为什么我不恢复以前的连接,例如 OnConnected() ?

【问题讨论】:

  • 您必须保护您的 SignalRUsers 列表免受多个线程的影响。因为多个线程可能会尝试对其进行操作,这可能会导致数据丢失。您可以使用 lock(SignalRUsers) 并使用此块内的列表。

标签: c# asp.net signalr signalr-hub


【解决方案1】:

每次客户端连接时,都会创建一个新的 Hub 对象实例。如果您的 SignalRUsers 是集线器的属性,则每次都是从头开始创建的。尝试将其设为静态属性或在容器中使用 Singleton。

【讨论】:

  • 为什么 OnConnected 可以让所有用户如此连接?
  • 你能分享完整的 hub 类吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多