using Furion.InstantMessaging; using Microsoft.AspNetCore.SignalR; namespace Admin.NET.Core; /// /// 聊天集线器 /// [MapHub("/hubs/chathub")] public class ChatHub : Hub { private readonly SysCacheService _sysCache; private readonly ISysMessageService _sysMessageService; private readonly SqlSugarRepository _sysOnlineUerRep; private readonly IHubContext _chatHubContext; public ChatHub(SysCacheService sysCache, ISysMessageService sysMessageService, SqlSugarRepository sysOnlineUerRep, IHubContext chatHubContext) { _sysCache = sysCache; _sysMessageService = sysMessageService; _sysOnlineUerRep = sysOnlineUerRep; _chatHubContext = chatHubContext; } /// /// 连接 /// /// 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 loginBrowser = client.UA.Family + client.UA.Major; var loginOs = client.OS.Family + client.OS.Major; var userId = claims.FirstOrDefault(e => e.Type == ClaimConst.UserId)?.Value; var account = claims.FirstOrDefault(e => e.Type == ClaimConst.UserName)?.Value; var name = claims.FirstOrDefault(e => e.Type == ClaimConst.RealName)?.Value; var tenantId = claims.FirstOrDefault(e => e.Type == ClaimConst.TenantId)?.Value; var user = new SysOnlineUser { ConnectionId = Context.ConnectionId, UserId = long.Parse(userId), LastTime = DateTime.Now, LastLoginIp = App.HttpContext.GetRemoteIpAddressToIPv4(), LastLoginBrowser = loginBrowser, LastLoginOs = loginOs, Account = account, Name = name, TenantId = Convert.ToInt64(tenantId), }; await _sysOnlineUerRep.AsInsertable(user).ExecuteCommandAsync(); //加入分组 以租户ID分组 方便后续通知 await _chatHubContext.Groups.AddToGroupAsync(Context.ConnectionId, $"{ChatHubPrefix.GROUP_ONLINE}{tenantId}"); var list = await _sysOnlineUerRep.AsQueryable().Filter("", true).Where(x => x.TenantId == user.TenantId).ToListAsync(); await _chatHubContext.Clients.Groups($"{ChatHubPrefix.GROUP_ONLINE}{user.TenantId}").OnlineUserChanged(new OnlineUserChangedDto { Name = user.Name, Offline = false, List = list }); //onlineUsers.Add(); //await _cache.SetAsync($"{CacheConst.KeyOnlineUser}{ Context.ConnectionId}", user); //await _sendMessageService.SendMessageToUserByConnectionId("asdasd但凡生得分", "下线吧", MessageTypeEnum.Offline, Context.ConnectionId); } /// /// 断开 /// /// /// public override async Task OnDisconnectedAsync(Exception exception) { if (!string.IsNullOrEmpty(Context.ConnectionId)) { var user = await _sysOnlineUerRep.AsQueryable().Filter("", true).FirstAsync(x => x.ConnectionId == Context.ConnectionId); if (user == null) return; await _sysOnlineUerRep.DeleteAsync(x => x.Id == user.Id); //通知当前组用户变动 var list = await _sysOnlineUerRep.AsQueryable().Filter("", true).Where(x => x.TenantId == user.TenantId).ToListAsync(); await _chatHubContext.Clients.Groups($"{ChatHubPrefix.GROUP_ONLINE}{user.TenantId}").OnlineUserChanged(new OnlineUserChangedDto { Name = user.Name, Offline = true, List = list }); //var onlineUsers = await _cache.GetAsync>(CacheConst.KeyOnlineUser); //if (onlineUsers == null) return; //onlineUsers.RemoveAll(u => u.ConnectionId == Context.ConnectionId); //await _cache.RemoveAsync($"{CacheConst.KeyOnlineUser}{ Context.ConnectionId}"); } } /// /// 强制下线 /// /// /// public async Task ForceExistUser(ForceExistUserRequest request) { await _chatHubContext.Clients.Client(request.ConnectionId).ForceExist("强制下线"); } /// /// 前端调用发送方法(发送信息给某个人) /// /// /// public async Task ClientsSendMessage(MessageInput message) { await _sysMessageService.SendMessageToUser(message); } /// /// 前端调用发送方法(发送信息给所有人) /// /// /// public async Task ClientsSendMessagetoAll(MessageInput message) { await _sysMessageService.SendMessageToAllUser(message); } /// /// 前端调用发送方法(发送消息给除了发送人的其他人) /// /// /// public async Task ClientsSendMessagetoOther(MessageInput message) { // _message.userId为发送人ID await _sysMessageService.SendMessageToOtherUser(message); } /// /// 前端调用发送方法(发送消息给某些人) /// /// /// public async Task ClientsSendMessagetoUsers(MessageInput message) { await _sysMessageService.SendMessageToUsers(message); } }