using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.SignalR; namespace ChatSample { public class InMemoryUserTracker : IUserTracker { private readonly ConcurrentDictionary _usersOnline = new ConcurrentDictionary(); public event Action UsersJoined; public event Action UsersLeft; public Task> UsersOnline() => Task.FromResult(_usersOnline.Values.AsEnumerable()); public Task AddUser(HubConnectionContext connection, UserDetails userDetails) { _usersOnline.TryAdd(connection, userDetails); UsersJoined(new[] { userDetails }); return Task.CompletedTask; } public Task RemoveUser(HubConnectionContext connection) { if (_usersOnline.TryRemove(connection, out var userDetails)) { UsersLeft(new[] { userDetails }); } return Task.CompletedTask; } } }