diff --git a/src/Application/Common/Interfaces/Identity/IUsersStateContainer.cs b/src/Application/Common/Interfaces/Identity/IUsersStateContainer.cs index f95041286..f68bf7806 100644 --- a/src/Application/Common/Interfaces/Identity/IUsersStateContainer.cs +++ b/src/Application/Common/Interfaces/Identity/IUsersStateContainer.cs @@ -5,6 +5,6 @@ public interface IUsersStateContainer { ConcurrentDictionary UsersByConnectionId { get; } event Action? OnChange; - void Update(string connectionId, string? name); + void AddOrUpdate(string connectionId, string? name); void Remove(string connectionId); } diff --git a/src/Application/Constants/ConstantString.cs b/src/Application/Constants/ConstantString.cs index 81ff3fcff..4834fa18f 100644 --- a/src/Application/Constants/ConstantString.cs +++ b/src/Application/Constants/ConstantString.cs @@ -45,7 +45,7 @@ public static class ConstantString public static string SaveSuccess => Localize("Save successfully"); public static string DeleteSuccess => Localize("Delete successfully"); public static string DeleteFail => Localize("Delete fail"); - public static string UpdateSuccess => Localize("Update successfully"); + public static string UpdateSuccess => Localize("AddOrUpdate successfully"); public static string CreateSuccess => Localize("Create successfully"); public static string LoginSuccess => Localize("Login successfully"); public static string LogoutSuccess => Localize("Logout successfully"); diff --git a/src/Application/Resources/Constants/ConstantString.Designer.cs b/src/Application/Resources/Constants/ConstantString.Designer.cs index 804a7ea83..37bcfd347 100644 --- a/src/Application/Resources/Constants/ConstantString.Designer.cs +++ b/src/Application/Resources/Constants/ConstantString.Designer.cs @@ -484,11 +484,11 @@ internal static string Sign_in_with__0_ { } /// - /// Looks up a localized string similar to Update successfully. + /// Looks up a localized string similar to AddOrUpdate successfully. /// internal static string Update_successfully { get { - return ResourceManager.GetString("Update successfully", resourceCulture); + return ResourceManager.GetString("AddOrUpdate successfully", resourceCulture); } } diff --git a/src/Blazor.Server.UI/Pages/Documents/_UploadFilesFormDialog.razor b/src/Blazor.Server.UI/Pages/Documents/_UploadFilesFormDialog.razor index 06db5ad84..8a2fb6e86 100644 --- a/src/Blazor.Server.UI/Pages/Documents/_UploadFilesFormDialog.razor +++ b/src/Blazor.Server.UI/Pages/Documents/_UploadFilesFormDialog.razor @@ -103,7 +103,7 @@ { System.Buffers.ArrayPool.Shared.Return(buffer); - // Update the UI with the final progress + // AddOrUpdate the UI with the final progress StateHasChanged(); } } diff --git a/src/Blazor.Server.UI/Shared/UserLoginState.razor b/src/Blazor.Server.UI/Shared/UserLoginState.razor index 511d944c2..cf14e2c2c 100644 --- a/src/Blazor.Server.UI/Shared/UserLoginState.razor +++ b/src/Blazor.Server.UI/Shared/UserLoginState.razor @@ -22,6 +22,8 @@ } [Inject] private HubClient Client { get; set; } = default!; + [Inject] + private IUsersStateContainer UsersStateContainer { get; set; } = default!; protected override async Task OnInitializedAsync() { Client.Login += _client_Login; @@ -36,20 +38,21 @@ } } - private void _client_Login(object? sender, string username) + private void _client_Login(object? sender, UserStateChangeEventArgs args) { InvokeAsync(() => { - Snackbar.Add(string.Format(L["{0} has logged in."],username), MudBlazor.Severity.Info); - + Snackbar.Add(string.Format(L["{0} has logged in."], args.UserName), MudBlazor.Severity.Info); + UsersStateContainer.AddOrUpdate(args.ConnectionId, args.UserName); }); } - private void _client_Logout(object? sender, string username) + private void _client_Logout(object? sender, UserStateChangeEventArgs args) { InvokeAsync(() => { - Snackbar.Add(string.Format(L["{0} has logged out."],username), MudBlazor.Severity.Normal); + Snackbar.Add(string.Format(L["{0} has logged out."], args.UserName), MudBlazor.Severity.Normal); + UsersStateContainer.Remove(args.ConnectionId); }); } diff --git a/src/Blazor.Server.UI/appsettings.json b/src/Blazor.Server.UI/appsettings.json index 297cc343e..41b0309c2 100644 --- a/src/Blazor.Server.UI/appsettings.json +++ b/src/Blazor.Server.UI/appsettings.json @@ -1,10 +1,10 @@ { "UseInMemoryDatabase": false, "DatabaseSettings": { - "DBProvider": "sqlite", - "ConnectionString": "Data Source=BlazorDashboardDb.db" - //"DBProvider": "mssql", - //"ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=BlazorDashboardDb;Trusted_Connection=True;MultipleActiveResultSets=true;" + //"DBProvider": "sqlite", + //"ConnectionString": "Data Source=BlazorDashboardDb.db" + "DBProvider": "mssql", + "ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=BlazorDashboardDb;Trusted_Connection=True;MultipleActiveResultSets=true;" //"DBProvider": "postgresql", //"ConnectionString": "Server=127.0.0.1;Database=BlazorDashboardDb;User Id=postgres;Password=postgrespw;Port=32768" }, diff --git a/src/Infrastructure/Extensions/SerilogExtensions.cs b/src/Infrastructure/Extensions/SerilogExtensions.cs index 3d8a250bc..7ac83bb06 100644 --- a/src/Infrastructure/Extensions/SerilogExtensions.cs +++ b/src/Infrastructure/Extensions/SerilogExtensions.cs @@ -26,7 +26,7 @@ public static void RegisterSerilog(this WebApplicationBuilder builder) .MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Error) .MinimumLevel.Override("MudBlazor", LogEventLevel.Information) .MinimumLevel.Override("Serilog", LogEventLevel.Error) - .MinimumLevel.Override("Microsoft.EntityFrameworkCore.Update", LogEventLevel.Error) + .MinimumLevel.Override("Microsoft.EntityFrameworkCore.AddOrUpdate", LogEventLevel.Error) .MinimumLevel.Override("Hangfire.BackgroundJobServer", LogEventLevel.Error) .MinimumLevel.Override("Hangfire.Server.BackgroundServerProcess", LogEventLevel.Error) .MinimumLevel.Override("Hangfire.Server.ServerHeartbeatProcess", LogEventLevel.Error) diff --git a/src/Infrastructure/Extensions/SignalRServiceCollectionExtensions.cs b/src/Infrastructure/Extensions/SignalRServiceCollectionExtensions.cs index d74e717ba..0368ecca9 100644 --- a/src/Infrastructure/Extensions/SignalRServiceCollectionExtensions.cs +++ b/src/Infrastructure/Extensions/SignalRServiceCollectionExtensions.cs @@ -8,7 +8,6 @@ public static class SignalRServiceCollectionExtensions public static void AddSignalRServices(this IServiceCollection services) { services.AddSingleton() - .AddScoped() .AddScoped() .AddSignalR(); } diff --git a/src/Infrastructure/Hubs/HubClient.cs b/src/Infrastructure/Hubs/HubClient.cs index b1e1d9efc..d833b79b3 100644 --- a/src/Infrastructure/Hubs/HubClient.cs +++ b/src/Infrastructure/Hubs/HubClient.cs @@ -24,8 +24,8 @@ public HubClient(NavigationManager navigationManager, AccessTokenProvider authPr }) .Build(); _hubConnection.ServerTimeout = TimeSpan.FromSeconds(30); - _hubConnection.On(SignalR.OnConnect, userId => { Login?.Invoke(this, userId); }); - _hubConnection.On(SignalR.OnDisconnect, userId => { Logout?.Invoke(this, userId); }); + _hubConnection.On(SignalR.OnConnect, (connectionId, userName) => { Login?.Invoke(this, new UserStateChangeEventArgs(connectionId,userName)); }); + _hubConnection.On(SignalR.OnDisconnect, (connectionId, userName) => { Logout?.Invoke(this, new UserStateChangeEventArgs(connectionId, userName)); }); _hubConnection.On(SignalR.SendNotification, message => { NotificationReceived?.Invoke(this, message); }); _hubConnection.On(SignalR.SendMessage, HandleReceiveMessage); @@ -77,22 +77,34 @@ public async Task NotifyAsync(string message) await _hubConnection.SendAsync(SignalR.SendNotification, message); } - public event EventHandler? Login; + public event EventHandler? Login; public event EventHandler? JobStarted; public event EventHandler? JobCompleted; - public event EventHandler? Logout; + public event EventHandler? Logout; public event EventHandler? NotificationReceived; public event MessageReceivedEventHandler? MessageReceived; - public class MessageReceivedEventArgs : EventArgs + +} +public class MessageReceivedEventArgs : EventArgs +{ + public MessageReceivedEventArgs(string userName, string message) { - public MessageReceivedEventArgs(string userId, string message) - { - UserId = userId; - Message = message; - } + UserId = userName; + Message = message; + } - public string UserId { get; set; } - public string Message { get; set; } + public string UserId { get; set; } + public string Message { get; set; } +} + +public class UserStateChangeEventArgs : EventArgs +{ + public UserStateChangeEventArgs(string connectionId, string userName) + { + ConnectionId = connectionId; + UserName = userName; } + public string ConnectionId { get; set; } + public string UserName { get; set; } } \ No newline at end of file diff --git a/src/Infrastructure/Hubs/SignalRHub.cs b/src/Infrastructure/Hubs/SignalRHub.cs index 855ac8a27..d2780c8df 100644 --- a/src/Infrastructure/Hubs/SignalRHub.cs +++ b/src/Infrastructure/Hubs/SignalRHub.cs @@ -14,8 +14,8 @@ public interface ISignalRHub Task Completed(string message); Task SendMessage(string from, string message); Task SendPrivateMessage(string from, string to, string message); - Task Disconnect(string userId); - Task Connect(string userId); + Task Disconnect(string connectionId, string userName); + Task Connect(string connectionId, string userName); Task SendNotification(string message); } @@ -26,19 +26,19 @@ public class SignalRHub : Hub public override async Task OnConnectedAsync() { - var id = Context.ConnectionId; + var connectionId = Context.ConnectionId; var username = Context.User?.Identity?.Name ?? string.Empty; - if (!OnlineUsers.ContainsKey(id)) OnlineUsers.TryAdd(id, username); + if (!OnlineUsers.ContainsKey(connectionId)) OnlineUsers.TryAdd(connectionId, username); - await Clients.All.Connect(username); + await Clients.All.Connect(connectionId,username); await base.OnConnectedAsync(); } public override async Task OnDisconnectedAsync(Exception? exception) { - var id = Context.ConnectionId; + var connectionId = Context.ConnectionId; //try to remove key from dictionary - if (OnlineUsers.TryRemove(id, out var username)) await Clients.All.Disconnect(username); + if (OnlineUsers.TryRemove(connectionId, out var username)) await Clients.All.Disconnect(connectionId,username); await base.OnConnectedAsync(); } diff --git a/src/Infrastructure/Services/CircuitHandlerService.cs b/src/Infrastructure/Services/CircuitHandlerService.cs deleted file mode 100644 index 641968d60..000000000 --- a/src/Infrastructure/Services/CircuitHandlerService.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Microsoft.AspNetCore.Components.Server.Circuits; - -namespace CleanArchitecture.Blazor.Infrastructure.Services; -public class CircuitHandlerService : CircuitHandler -{ - - private readonly IUsersStateContainer _usersStateContainer; - private readonly AuthenticationStateProvider _authenticationStateProvider; - - public CircuitHandlerService(IUsersStateContainer usersStateContainer, AuthenticationStateProvider authenticationStateProvider) - { - _usersStateContainer = usersStateContainer; - _authenticationStateProvider = authenticationStateProvider; - } - - public override async Task OnConnectionUpAsync(Circuit circuit, - CancellationToken cancellationToken) - { - var state = await _authenticationStateProvider.GetAuthenticationStateAsync(); - if (state is not null && state.User.Identity is not null && state.User.Identity.IsAuthenticated) - { - _usersStateContainer.Update(circuit.Id, state.User.Identity.Name); - } - } - - public override Task OnConnectionDownAsync(Circuit circuit, - CancellationToken cancellationToken) - { - _usersStateContainer.Remove(circuit.Id); - return Task.CompletedTask; - } - -} \ No newline at end of file diff --git a/src/Infrastructure/Services/Identity/UsersStateContainer.cs b/src/Infrastructure/Services/Identity/UsersStateContainer.cs index 77d2b966b..e1dfa79c6 100644 --- a/src/Infrastructure/Services/Identity/UsersStateContainer.cs +++ b/src/Infrastructure/Services/Identity/UsersStateContainer.cs @@ -6,7 +6,7 @@ public class UsersStateContainer : IUsersStateContainer public ConcurrentDictionary UsersByConnectionId { get; } = new ConcurrentDictionary(); public event Action? OnChange; - public void Update(string connectionId, string? name) + public void AddOrUpdate(string connectionId, string? name) { UsersByConnectionId.AddOrUpdate(connectionId, name??String.Empty, (key, oldValue) => name??String.Empty); NotifyStateChanged();