using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using Abp.Collections.Extensions; using Abp.Dependency; using Abp.Extensions; using JetBrains.Annotations; namespace Abp.RealTime { public class OnlineClientManager : OnlineClientManager, IOnlineClientManager { } /// /// Implements . /// public class OnlineClientManager : IOnlineClientManager, ISingletonDependency { public event EventHandler ClientConnected; public event EventHandler ClientDisconnected; public event EventHandler UserConnected; public event EventHandler UserDisconnected; /// /// Online clients. /// protected ConcurrentDictionary Clients { get; } protected readonly object SyncObj = new object(); /// /// Initializes a new instance of the class. /// public OnlineClientManager() { Clients = new ConcurrentDictionary(); } public virtual void Add(IOnlineClient client) { lock (SyncObj) { var userWasAlreadyOnline = false; var user = client.ToUserIdentifierOrNull(); if (user != null) { userWasAlreadyOnline = this.IsOnline(user); } Clients[client.ConnectionId] = client; ClientConnected.InvokeSafely(this, new OnlineClientEventArgs(client)); if (user != null && !userWasAlreadyOnline) { UserConnected.InvokeSafely(this, new OnlineUserEventArgs(user, client)); } } } public virtual bool Remove(string connectionId) { lock (SyncObj) { IOnlineClient client; var isRemoved = Clients.TryRemove(connectionId, out client); if (isRemoved) { var user = client.ToUserIdentifierOrNull(); if (user != null && !this.IsOnline(user)) { UserDisconnected.InvokeSafely(this, new OnlineUserEventArgs(user, client)); } ClientDisconnected.InvokeSafely(this, new OnlineClientEventArgs(client)); } return isRemoved; } } public virtual IOnlineClient GetByConnectionIdOrNull(string connectionId) { lock (SyncObj) { return Clients.GetOrDefault(connectionId); } } public virtual IReadOnlyList GetAllClients() { lock (SyncObj) { return Clients.Values.ToImmutableList(); } } [NotNull] public virtual IReadOnlyList GetAllByUserId([NotNull] IUserIdentifier user) { Check.NotNull(user, nameof(user)); return GetAllClients() .Where(c => (c.UserId == user.UserId && c.TenantId == user.TenantId)) .ToImmutableList(); } } }