// 麻省理工学院许可证 // // 版权所有 (c) 2021-2023 zuohuaijun,大名科技(天津)有限公司 联系电话/微信:18020030720 QQ:515096995 // // 特此免费授予获得本软件的任何人以处理本软件的权利,但须遵守以下条件:在所有副本或重要部分的软件中必须包括上述版权声明和本许可声明。 // // 软件按“原样”提供,不提供任何形式的明示或暗示的保证,包括但不限于对适销性、适用性和非侵权的保证。 // 在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任负责,无论是因合同、侵权或其他方式引起的,与软件或其使用或其他交易有关。 using Furion.InstantMessaging; using Microsoft.AspNetCore.SignalR; namespace Admin.NET.Core; /// /// 在线用户集线器 /// [MapHub("/hubs/onlineUser")] public class OnlineUserHub : Hub { private const string GROUP_ONLINE = "GROUP_ONLINE_"; // 租户分组前缀 private readonly SqlSugarRepository _sysOnlineUerRep; private readonly SysMessageService _sysMessageService; private readonly IHubContext _onlineUserHubContext; private readonly SysCacheService _sysCacheService; public OnlineUserHub(SqlSugarRepository sysOnlineUerRep, SysMessageService sysMessageService, IHubContext onlineUserHubContext, SysCacheService sysCacheService) { _sysOnlineUerRep = sysOnlineUerRep; _sysMessageService = sysMessageService; _onlineUserHubContext = onlineUserHubContext; _sysCacheService = sysCacheService; } /// /// 连接 /// /// public override async Task OnConnectedAsync() { var token = Context.GetHttpContext().Request.Query["access_token"]; var claims = JWTEncryption.ReadJwtToken(token)?.Claims; var client = Parser.GetDefault().Parse(Context.GetHttpContext().Request.Headers["User-Agent"]); var userId = claims.FirstOrDefault(u => u.Type == ClaimConst.UserId)?.Value; var tenantId = claims.FirstOrDefault(u => u.Type == ClaimConst.TenantId)?.Value; var user = new SysOnlineUser { ConnectionId = Context.ConnectionId, UserId = string.IsNullOrWhiteSpace(userId) ? 0 : long.Parse(userId), UserName = claims.FirstOrDefault(u => u.Type == ClaimConst.Account)?.Value, RealName = claims.FirstOrDefault(u => u.Type == ClaimConst.RealName)?.Value, Time = DateTime.Now, Ip = App.HttpContext.GetRemoteIpAddressToIPv4(), Browser = client.UA.Family + client.UA.Major, Os = client.OS.Family + client.OS.Major, TenantId = string.IsNullOrWhiteSpace(tenantId) ? 0 : Convert.ToInt64(tenantId), }; await _sysOnlineUerRep.InsertAsync(user); //缓存 _sysCacheService.Set(CacheConst.KeyUserOnline + user.UserId, 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 }); } /// /// 断开 /// /// /// public override async Task OnDisconnectedAsync(Exception exception) { if (string.IsNullOrEmpty(Context.ConnectionId)) return; 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); _sysCacheService.Remove(CacheConst.KeyUserOnline + user.UserId); // 通知当前组用户变动 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 }); } /// /// 强制下线 /// /// /// public async Task ForceOffline(OnlineUserHubInput input) { await _onlineUserHubContext.Clients.Client(input.ConnectionId).ForceOffline("强制下线"); } /// /// 前端调用发送方法(发送信息给某个人) /// /// /// public async Task ClientsSendMessage(MessageInput message) { await _sysMessageService.SendUser(message); } /// /// 前端调用发送方法(发送信息给所有人) /// /// /// public async Task ClientsSendMessagetoAll(MessageInput message) { await _sysMessageService.SendAllUser(message); } /// /// 前端调用发送方法(发送消息给除了发送人的其他人) /// /// /// public async Task ClientsSendMessagetoOther(MessageInput message) { await _sysMessageService.SendOtherUser(message); } /// /// 前端调用发送方法(发送消息给某些人) /// /// /// public async Task ClientsSendMessagetoUsers(MessageInput message) { await _sysMessageService.SendUsers(message); } }