【发布时间】: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