From f656ec32c12101ce875fc4a420f658292eec6c43 Mon Sep 17 00:00:00 2001 From: chenchun Date: Fri, 29 Nov 2024 14:58:10 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E5=9C=A8=E7=BA=BFhub?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/Monitor/OnlineService.cs | 15 ++-- .../SignalRHubs/OnlineHub.cs | 85 +++++++++---------- 2 files changed, 51 insertions(+), 49 deletions(-) diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/Monitor/OnlineService.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/Monitor/OnlineService.cs index 5691a705..2f2d8cbd 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/Monitor/OnlineService.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/Monitor/OnlineService.cs @@ -13,6 +13,7 @@ namespace Yi.Framework.Rbac.Application.Services.Monitor { private ILogger _logger; private IHubContext _hub; + public OnlineService(ILogger logger, IHubContext hub) { _logger = logger; @@ -26,18 +27,21 @@ namespace Yi.Framework.Rbac.Application.Services.Monitor /// public Task> GetListAsync([FromQuery] OnlineUserModel online) { - var data = OnlineHub.clientUsers; - IEnumerable dataWhere = data.AsEnumerable(); + var data = OnlineHub.ClientUsersDic; + IEnumerable dataWhere = data.Values.AsEnumerable(); if (!string.IsNullOrEmpty(online.Ipaddr)) { dataWhere = dataWhere.Where((u) => u.Ipaddr!.Contains(online.Ipaddr)); } + if (!string.IsNullOrEmpty(online.UserName)) { dataWhere = dataWhere.Where((u) => u.UserName!.Contains(online.UserName)); } - return Task.FromResult(new PagedResultDto() { TotalCount = data.Count, Items = dataWhere.ToList() }); + + return Task.FromResult(new PagedResultDto() + { TotalCount = data.Count, Items = dataWhere.ToList() }); } @@ -50,13 +54,14 @@ namespace Yi.Framework.Rbac.Application.Services.Monitor [Route("online/{connnectionId}")] public async Task ForceOut(string connnectionId) { - if (OnlineHub.clientUsers.Exists(u => u.ConnnectionId == connnectionId)) + if (OnlineHub.ClientUsersDic.ContainsKey(connnectionId)) { //前端接受到这个事件后,触发前端自动退出 await _hub.Clients.Client(connnectionId).SendAsync("forceOut", "你已被强制退出!"); return true; } + return false; } } -} +} \ No newline at end of file diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/SignalRHubs/OnlineHub.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/SignalRHubs/OnlineHub.cs index 5e7df65f..a55ef125 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/SignalRHubs/OnlineHub.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/SignalRHubs/OnlineHub.cs @@ -1,4 +1,5 @@ -using Microsoft.AspNetCore.Authorization; +using System.Collections.Concurrent; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.SignalR; using Microsoft.Extensions.Logging; @@ -13,53 +14,54 @@ namespace Yi.Framework.Rbac.Application.SignalRHubs //[Authorize] public class OnlineHub : AbpHub { - public static readonly List clientUsers = new(); - private readonly static object objLock = new object(); + public static ConcurrentDictionary ClientUsersDic { get; set; } = new(); - private HttpContext? _httpContext; + private readonly HttpContext? _httpContext; private ILogger _logger => LoggerFactory.CreateLogger(); + public OnlineHub(IHttpContextAccessor httpContextAccessor) { _httpContext = httpContextAccessor?.HttpContext; } - /// /// 成功连接 /// /// public override Task OnConnectedAsync() { - lock (objLock) + if (_httpContext is null) { - var name = CurrentUser.UserName; - var loginUser = new LoginLogAggregateRoot().GetInfoByHttpContext(_httpContext); - - OnlineUserModel user = new(Context.ConnectionId) - { - Browser = loginUser?.Browser, - LoginLocation = loginUser?.LoginLocation, - Ipaddr = loginUser?.LoginIp, - LoginTime = DateTime.Now, - Os = loginUser?.Os, - UserName = name ?? "Null", - UserId = CurrentUser.Id ?? Guid.Empty - }; - - //已登录 - if (CurrentUser.Id is not null) - { //先移除之前的用户id,一个用户只能一个 - clientUsers.RemoveAll(u => u.UserId == CurrentUser.Id); - _logger.LogInformation($"{DateTime.Now}:{name},{Context.ConnectionId}连接服务端success,当前已连接{clientUsers.Count}个"); - } - //全部移除之后,再进行添加 - clientUsers.RemoveAll(u => u.ConnnectionId == Context.ConnectionId); - - clientUsers.Add(user); - //当有人加入,向全部客户端发送当前总数 - Clients.All.SendAsync("onlineNum", clientUsers.Count); + return Task.CompletedTask; } + var name = CurrentUser.UserName; + var loginUser = new LoginLogAggregateRoot().GetInfoByHttpContext(_httpContext); + + OnlineUserModel user = new(Context.ConnectionId) + { + Browser = loginUser?.Browser, + LoginLocation = loginUser?.LoginLocation, + Ipaddr = loginUser?.LoginIp, + LoginTime = DateTime.Now, + Os = loginUser?.Os, + UserName = name ?? "Null", + UserId = CurrentUser.Id ?? Guid.Empty + }; + + //已登录 + if (CurrentUser.IsAuthenticated) + { + ClientUsersDic.RemoveAll(u => u.Value.UserId == CurrentUser.Id); + _logger.LogDebug( + $"{DateTime.Now}:{name},{Context.ConnectionId}连接服务端success,当前已连接{ClientUsersDic.Count}个"); + } + + ClientUsersDic.AddOrUpdate(Context.ConnectionId, user, (_, _) => user); + + //当有人加入,向全部客户端发送当前总数 + Clients.All.SendAsync("onlineNum", ClientUsersDic.Count); + return base.OnConnectedAsync(); } @@ -69,22 +71,17 @@ namespace Yi.Framework.Rbac.Application.SignalRHubs /// /// /// - public override Task OnDisconnectedAsync(Exception exception) + public override Task OnDisconnectedAsync(Exception? exception) { - lock (objLock) + //已登录 + if (CurrentUser.IsAuthenticated) { - //已登录 - if (CurrentUser.Id is not null) - { - clientUsers.RemoveAll(u => u.UserId == CurrentUser.Id); - _logger.LogInformation($"用户{CurrentUser?.UserName}离开了,当前已连接{clientUsers.Count}个"); - } - clientUsers.RemoveAll(u => u.ConnnectionId == Context.ConnectionId); - Clients.All.SendAsync("onlineNum", clientUsers.Count); + ClientUsersDic.RemoveAll(u => u.Value.UserId == CurrentUser.Id); + _logger.LogDebug($"用户{CurrentUser?.UserName}离开了,当前已连接{ClientUsersDic.Count}个"); } + ClientUsersDic.Remove(Context.ConnectionId, out _); + Clients.All.SendAsync("onlineNum", ClientUsersDic.Count); return base.OnDisconnectedAsync(exception); } - - } } \ No newline at end of file