using Infrastructure; using Infrastructure.Model; using IPTools.Core; using Microsoft.AspNetCore.SignalR; using System.Web; using UAParser; using ZR.Service.System.IService; namespace ZR.ServiceCore.Signalr { /// /// msghub /// public class MessageHub : Hub { //创建用户集合,用于存储所有链接的用户数据 public static readonly List onlineClients = new(); public static List users = new(); //private readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); private readonly ISysNoticeService SysNoticeService; public MessageHub(ISysNoticeService noticeService) { SysNoticeService = noticeService; } private ApiResult SendNotice() { var result = SysNoticeService.GetSysNotices(); return new ApiResult(200, "success", result); } #region 客户端连接 /// /// 客户端连接的时候调用 /// /// public override Task OnConnectedAsync() { var context = App.HttpContext; var name = HttpContextExtension.GetName(context); var ip = HttpContextExtension.GetClientUserIp(context); var ip_info = IpTool.Search(ip); ClientInfo clientInfo = HttpContextExtension.GetClientInfo(context); string device = clientInfo.ToString(); string qs = HttpContextExtension.GetQueryString(context); var query = HttpUtility.ParseQueryString(qs); string from = query.Get("from") ?? "web"; string clientId = query.Get("clientId"); long userid = HttpContextExtension.GetUId(context); string uuid = device + userid + ip; var user = onlineClients.Any(u => u.ConnnectionId == Context.ConnectionId); var user2 = onlineClients.Any(u => u.Uuid == uuid); //判断用户是否存在,否则添加集合!user2 && !user && if (!user2 && !user && Context.User.Identity.IsAuthenticated) { OnlineUsers onlineUser = new(Context.ConnectionId, name, userid, ip, device) { Location = ip_info.City, Uuid = uuid, Platform = from, ClientId = clientId ?? Context.ConnectionId }; onlineClients.Add(onlineUser); Log.WriteLine(msg: $"{name},{Context.ConnectionId}连接服务端success,当前已连接{onlineClients.Count}个"); //Clients.All.SendAsync("welcome", $"欢迎您:{name},当前时间:{DateTime.Now}"); Clients.Caller.SendAsync(HubsConstant.MoreNotice, SendNotice()); // Clients.Caller.SendAsync(HubsConstant.ConnId, onlineUser.ConnnectionId); } OnlineUsers userInfo = GetUserById(userid); if (userInfo == null) { userInfo = new OnlineUsers() { Userid = userid, Name = name, LoginTime = DateTime.Now }; users.Add(userInfo); } else { if (userInfo.LoginTime <= Convert.ToDateTime(DateTime.Now.ToShortDateString())) { userInfo.LoginTime = DateTime.Now; userInfo.TodayOnlineTime = 0; } var clientUser = onlineClients.Find(x => x.Userid == userid); userInfo.TodayOnlineTime += Math.Round(clientUser?.OnlineTime ?? 0, 2); } //给当前所有登录当前账号的用户下发登录时长 var connIds = onlineClients.Where(f => f.Userid == userid).ToList(); userInfo.ClientNum = connIds.Count; // Clients.Clients(connIds.Select(f => f.ConnnectionId)).SendAsync("onlineInfo", userInfo); Log.WriteLine(ConsoleColor.Blue, msg: $"用户{name}已连接,今日已在线{userInfo?.TodayOnlineTime}分钟,当前已连接{onlineClients.Count}个"); //给所有用户更新在线人数 Clients.All.SendAsync(HubsConstant.OnlineNum, new { num = onlineClients.Count, onlineClients }); return base.OnConnectedAsync(); } /// /// 连接终止时调用。 /// /// public override Task OnDisconnectedAsync(Exception exception) { var user = onlineClients.Where(p => p.ConnnectionId == Context.ConnectionId).FirstOrDefault(); if (user != null) { onlineClients.Remove(user); //给所有用户更新在线人数 Clients.All.SendAsync(HubsConstant.OnlineNum, new { num = onlineClients.Count, onlineClients, leaveUser = user }); //累计用户时长 OnlineUsers userInfo = GetUserById(user.Userid); if (userInfo != null) { userInfo.TodayOnlineTime += user?.OnlineTime ?? 0; } Log.WriteLine(ConsoleColor.Red, msg: $"用户{user?.Name}离开了,已在线{userInfo?.TodayOnlineTime}分,当前已连接{onlineClients.Count}个"); } return base.OnDisconnectedAsync(exception); } #endregion /// /// 发送信息 /// /// 对方链接id /// /// /// [HubMethodName("sendMessage")] public async Task SendMessage(string toConnectId, long toUserId, string message) { var userName = HttpContextExtension.GetName(App.HttpContext); long userid = HttpContextExtension.GetUId(App.HttpContext); var toUserList = onlineClients.Where(p => p.Userid == toUserId); var toUserInfo = toUserList.FirstOrDefault(); IList sendToUser = toUserList.Select(x => x.ConnnectionId).ToList(); sendToUser.Add(GetConnectId()); if (toUserInfo != null) { await Clients.Clients(sendToUser) .SendAsync("receiveChat", new { msgType = 0,//文本 chatid = Guid.NewGuid().ToString(), userName, userid, toUserName = toUserInfo.Name, toUserid = toUserInfo.Userid, message, chatTime = DateTime.Now }); } else { //TODO 存储离线消息 Console.WriteLine($"{toUserId}不在线"); } Console.WriteLine($"用户{userName}对{toConnectId}-{toUserId}说:{message}"); } private OnlineUsers GetUserByConnId(string connId) { return onlineClients.Where(p => p.ConnnectionId == connId).FirstOrDefault(); } private static OnlineUsers GetUserById(long userid) { return users.Where(f => f.Userid == userid).FirstOrDefault(); } /// /// 移动端使用获取链接id /// /// [HubMethodName("getConnId")] public string GetConnectId() { return Context.ConnectionId; } /// /// 退出其他设备登录 /// /// [HubMethodName("logOut")] public async Task LogOut() { var singleLogin = AppSettings.Get("singleLogin"); long userid = HttpContextExtension.GetUId(App.HttpContext); if (singleLogin) { var onlineUsers = onlineClients.Where(p => p.ConnnectionId != Context.ConnectionId && p.Userid == userid); await Clients.Clients(onlineUsers.Select(x => x.ConnnectionId)) .SendAsync("logOut"); } } } }