// Admin.NET 项目的版æƒã€å•†æ ‡ã€ä¸“利和其他相关æƒåˆ©å‡å—ç›¸åº”æ³•å¾‹æ³•è§„çš„ä¿æŠ¤ã€‚ä½¿ç”¨æœ¬é¡¹ç›®åº”éµå®ˆç›¸å…³æ³•律法规和许å¯è¯çš„è¦æ±‚。 // // 本项目主è¦éµå¾ª MIT 许å¯è¯å’Œ Apache 许å¯è¯ï¼ˆç‰ˆæœ¬ 2.0)进行分å‘和使用。许å¯è¯ä½äºŽæºä»£ç æ ‘æ ¹ç›®å½•ä¸çš„ LICENSE-MIT å’Œ LICENSE-APACHE 文件。 // // ä¸å¾—利用本项目从事å±å®³å›½å®¶å®‰å…¨ã€æ‰°ä¹±ç¤¾ä¼šç§©åºã€ä¾µçŠ¯ä»–äººåˆæ³•æƒç›Šç‰æ³•å¾‹æ³•è§„ç¦æ¢çš„æ´»åЍï¼ä»»ä½•基于本项目二次开å‘è€Œäº§ç”Ÿçš„ä¸€åˆ‡æ³•å¾‹çº çº·å’Œè´£ä»»ï¼Œæˆ‘ä»¬ä¸æ‰¿æ‹…ä»»ä½•è´£ä»»ï¼ using Furion.InstantMessaging; using Microsoft.AspNetCore.SignalR; namespace Admin.NET.Core; /// <summary> /// 在线用户集线器 /// </summary> [MapHub("/hubs/onlineUser")] public class OnlineUserHub : Hub<IOnlineUserHub> { private const string GROUP_ONLINE = "GROUP_ONLINE_"; // 租户分组å‰ç¼€ private readonly SqlSugarRepository<SysOnlineUser> _sysOnlineUerRep; private readonly SysMessageService _sysMessageService; private readonly IHubContext<OnlineUserHub, IOnlineUserHub> _onlineUserHubContext; private readonly SysCacheService _sysCacheService; private readonly SysConfigService _sysConfigService; public OnlineUserHub(SqlSugarRepository<SysOnlineUser> sysOnlineUerRep, SysMessageService sysMessageService, IHubContext<OnlineUserHub, IOnlineUserHub> onlineUserHubContext, SysCacheService sysCacheService, SysConfigService sysConfigService) { _sysOnlineUerRep = sysOnlineUerRep; _sysMessageService = sysMessageService; _onlineUserHubContext = onlineUserHubContext; _sysCacheService = sysCacheService; _sysConfigService = sysConfigService; } /// <summary> /// 连接 /// </summary> /// <returns></returns> public override async Task OnConnectedAsync() { var httpContext = Context.GetHttpContext(); var userId = (httpContext.User.FindFirst(ClaimConst.UserId)?.Value).ToLong(); var account = httpContext.User.FindFirst(ClaimConst.Account)?.Value; var realName = httpContext.User.FindFirst(ClaimConst.RealName)?.Value; var tenantId = (httpContext.User.FindFirst(ClaimConst.TenantId)?.Value).ToLong(); var user = new SysOnlineUser { ConnectionId = Context.ConnectionId, UserId = userId, UserName = account, RealName = realName, Time = DateTime.Now, Ip = httpContext.GetRemoteIpAddressToIPv4(true), Browser = httpContext.GetClientBrowser(), Os = httpContext.GetClientOs(), TenantId = tenantId, }; await _sysOnlineUerRep.InsertAsync(user); // 是å¦å¼€å¯å•用户登录 if (await _sysConfigService.GetConfigValue<bool>(ConfigConst.SysSingleLogin)) { _sysCacheService.Set(CacheConst.KeyUserOnline + user.UserId, user); } else { var device = httpContext.GetClientDeviceInfo().Trim(); _sysCacheService.Set(CacheConst.KeyUserOnline + user.UserId + device, user); } // 以租户Id进行分组 var groupName = $"{GROUP_ONLINE}{user.TenantId}"; await _onlineUserHubContext.Groups.AddToGroupAsync(Context.ConnectionId, groupName); var userList = await _sysOnlineUerRep.AsQueryable().Filter("", true) .Where(u => u.TenantId == user.TenantId).Take(10).ToListAsync(); await _onlineUserHubContext.Clients.Groups(groupName).OnlineUserList(new OnlineUserList { RealName = user.RealName, Online = true, UserList = userList }); } /// <summary> /// æ–å¼€ /// </summary> /// <param name="exception"></param> /// <returns></returns> public override async Task OnDisconnectedAsync(Exception exception) { if (string.IsNullOrEmpty(Context.ConnectionId)) return; var httpContext = Context.GetHttpContext(); var user = await _sysOnlineUerRep.AsQueryable().Filter("", true).FirstAsync(u => u.ConnectionId == Context.ConnectionId); if (user == null) return; await _sysOnlineUerRep.DeleteAsync(u => u.Id == user.Id); // 是å¦å¼€å¯å•用户登录 if (await _sysConfigService.GetConfigValue<bool>(ConfigConst.SysSingleLogin)) { _sysCacheService.Remove(CacheConst.KeyUserOnline + user.UserId); } else { var device = httpContext.GetClientDeviceInfo().Trim(); _sysCacheService.Remove(CacheConst.KeyUserOnline + user.UserId + device); } // 通知当å‰ç»„用户å˜åЍ var userList = await _sysOnlineUerRep.AsQueryable().Filter("", true) .Where(u => u.TenantId == user.TenantId).Take(10).ToListAsync(); await _onlineUserHubContext.Clients.Groups($"{GROUP_ONLINE}{user.TenantId}").OnlineUserList(new OnlineUserList { RealName = user.RealName, Online = false, UserList = userList }); } /// <summary> /// 强制下线 /// </summary> /// <param name="input"></param> /// <returns></returns> public async Task ForceOffline(OnlineUserHubInput input) { await _onlineUserHubContext.Clients.Client(input.ConnectionId).ForceOffline("强制下线"); } /// <summary> /// å‘é€ä¿¡æ¯ç»™æŸä¸ªäºº /// </summary> /// <param name="message"></param> /// <returns></returns> public async Task ClientsSendMessage(MessageInput message) { await _sysMessageService.SendUser(message); } /// <summary> /// å‘é€ä¿¡æ¯ç»™æ‰€æœ‰äºº /// </summary> /// <param name="message"></param> /// <returns></returns> public async Task ClientsSendMessagetoAll(MessageInput message) { await _sysMessageService.SendAllUser(message); } /// <summary> /// å‘逿¶ˆæ¯ç»™æŸäº›äººï¼ˆé™¤äº†æœ¬äººï¼‰ /// </summary> /// <param name="message"></param> /// <returns></returns> public async Task ClientsSendMessagetoOther(MessageInput message) { await _sysMessageService.SendOtherUser(message); } /// <summary> /// å‘逿¶ˆæ¯ç»™æŸäº›äºº /// </summary> /// <param name="message"></param> /// <returns></returns> public async Task ClientsSendMessagetoUsers(MessageInput message) { await _sysMessageService.SendUsers(message); } }