OnlineClientManager.cs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. using System;
  2. using System.Collections.Concurrent;
  3. using System.Collections.Generic;
  4. using System.Collections.Immutable;
  5. using System.Linq;
  6. using Abp.Collections.Extensions;
  7. using Abp.Dependency;
  8. using Abp.Extensions;
  9. using JetBrains.Annotations;
  10. namespace Abp.RealTime
  11. {
  12. public class OnlineClientManager<T> : OnlineClientManager, IOnlineClientManager<T>
  13. {
  14. }
  15. /// <summary>
  16. /// Implements <see cref="IOnlineClientManager"/>.
  17. /// </summary>
  18. public class OnlineClientManager : IOnlineClientManager, ISingletonDependency
  19. {
  20. public event EventHandler<OnlineClientEventArgs> ClientConnected;
  21. public event EventHandler<OnlineClientEventArgs> ClientDisconnected;
  22. public event EventHandler<OnlineUserEventArgs> UserConnected;
  23. public event EventHandler<OnlineUserEventArgs> UserDisconnected;
  24. /// <summary>
  25. /// Online clients.
  26. /// </summary>
  27. protected ConcurrentDictionary<string, IOnlineClient> Clients { get; }
  28. protected readonly object SyncObj = new object();
  29. /// <summary>
  30. /// Initializes a new instance of the <see cref="OnlineClientManager"/> class.
  31. /// </summary>
  32. public OnlineClientManager()
  33. {
  34. Clients = new ConcurrentDictionary<string, IOnlineClient>();
  35. }
  36. public virtual void Add(IOnlineClient client)
  37. {
  38. lock (SyncObj)
  39. {
  40. var userWasAlreadyOnline = false;
  41. var user = client.ToUserIdentifierOrNull();
  42. if (user != null)
  43. {
  44. userWasAlreadyOnline = this.IsOnline(user);
  45. }
  46. Clients[client.ConnectionId] = client;
  47. ClientConnected.InvokeSafely(this, new OnlineClientEventArgs(client));
  48. if (user != null && !userWasAlreadyOnline)
  49. {
  50. UserConnected.InvokeSafely(this, new OnlineUserEventArgs(user, client));
  51. }
  52. }
  53. }
  54. public virtual bool Remove(string connectionId)
  55. {
  56. lock (SyncObj)
  57. {
  58. IOnlineClient client;
  59. var isRemoved = Clients.TryRemove(connectionId, out client);
  60. if (isRemoved)
  61. {
  62. var user = client.ToUserIdentifierOrNull();
  63. if (user != null && !this.IsOnline(user))
  64. {
  65. UserDisconnected.InvokeSafely(this, new OnlineUserEventArgs(user, client));
  66. }
  67. ClientDisconnected.InvokeSafely(this, new OnlineClientEventArgs(client));
  68. }
  69. return isRemoved;
  70. }
  71. }
  72. public virtual IOnlineClient GetByConnectionIdOrNull(string connectionId)
  73. {
  74. lock (SyncObj)
  75. {
  76. return Clients.GetOrDefault(connectionId);
  77. }
  78. }
  79. public virtual IReadOnlyList<IOnlineClient> GetAllClients()
  80. {
  81. lock (SyncObj)
  82. {
  83. return Clients.Values.ToImmutableList();
  84. }
  85. }
  86. [NotNull]
  87. public virtual IReadOnlyList<IOnlineClient> GetAllByUserId([NotNull] IUserIdentifier user)
  88. {
  89. Check.NotNull(user, nameof(user));
  90. return GetAllClients()
  91. .Where(c => (c.UserId == user.UserId && c.TenantId == user.TenantId))
  92. .ToImmutableList();
  93. }
  94. }
  95. }