UNIVPLMDataIntegration/Admin.NET/Admin.NET.Core/Hub/OnlineUserHub.cs
2025-09-05 00:45:32 +08:00

131 lines
5.1 KiB
C#

// 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 SysMessageService _sysMessageService;
private readonly IHubContext<OnlineUserHub, IOnlineUserHub> _onlineUserHubContext;
public OnlineUserHub(SysMessageService sysMessageService,
IHubContext<OnlineUserHub, IOnlineUserHub> onlineUserHubContext)
{
_sysMessageService = sysMessageService;
_onlineUserHubContext = onlineUserHubContext;
}
/// <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;
if (userId < 0 || string.IsNullOrWhiteSpace(account)) return;
var realName = httpContext.User.FindFirst(ClaimConst.RealName)?.Value;
var tenantId = (httpContext.User.FindFirst(ClaimConst.TenantId)?.Value).ToLong();
var loginMode = (LoginModeEnum)(httpContext.User.FindFirst(ClaimConst.LoginMode)?.Value).ToInt();
loginMode = loginMode == 0 ? LoginModeEnum.PC : loginMode; // 默认PC登录模式
var device = httpContext.GetClientDeviceInfo().Trim();
var ipAddress = httpContext.Request.Headers["X-Forwarded-For"].FirstOrDefault();
var user = new OnlineUser
{
ConnectionId = Context.ConnectionId,
UserId = userId,
UserName = account,
RealName = realName,
Time = DateTime.Now,
Ip = string.IsNullOrWhiteSpace(ipAddress) ? httpContext.GetRemoteIpAddressToIPv4(true) : ipAddress,
Browser = httpContext.GetClientBrowser(),
Os = httpContext.GetClientOs(),
TenantId = tenantId,
LoginMode = loginMode,
Device = device
};
SysCacheService.HashAdd(CacheConst.KeyUserOnline, Context.ConnectionId, user);
// 以租户Id进行分组
var groupName = $"{GROUP_ONLINE}{user.TenantId}";
await _onlineUserHubContext.Groups.AddToGroupAsync(Context.ConnectionId, groupName);
// 更新在线用户列表
var userList = SysCacheService.HashGetAll<OnlineUser>(CacheConst.KeyUserOnline).Values.Where(u => u.TenantId == tenantId).ToList();
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 user = SysCacheService.HashGetOne<OnlineUser>(CacheConst.KeyUserOnline, Context.ConnectionId);
if (user == null) return;
SysCacheService.HashDel<OnlineUser>(CacheConst.KeyUserOnline, Context.ConnectionId);
// 更新在线用户列表
var userList = SysCacheService.HashGetAll<OnlineUser>(CacheConst.KeyUserOnline).Values.Where(u => u.TenantId == user.TenantId).ToList();
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 SendMessageToUser(MessageInput message)
{
await _sysMessageService.SendUser(message);
}
/// <summary>
/// 发送信息给所有人
/// </summary>
/// <param name="message"></param>
/// <returns></returns>
public async Task SendMessageToAllUser(MessageInput message)
{
await _sysMessageService.SendAllUser(message);
}
}