BootstrapAdmin/Bootstrap.Admin/Controllers/Api/OnlineUsersController.cs

141 lines
4.1 KiB
C#

using Longbow.Web;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading;
namespace Bootstrap.Admin.Controllers.Api
{
/// <summary>
/// 在线用户接口
/// </summary>
[Route("api/[controller]")]
[ApiController]
public class OnlineUsersController : ControllerBase
{
/// <summary>
/// 获取所有在线用户数据
/// </summary>
/// <returns></returns>
[HttpGet()]
public IEnumerable<OnlineUser> Get([FromServices]IOnlineUsers onlineUSers)
{
return onlineUSers.OnlineUsers.OrderByDescending(u => u.LastAccessTime);
}
/// <summary>
/// 获取指定会话的在线用户请求地址明细数据
/// </summary>
/// <param name="id"></param>
/// <param name="onlineUSers"></param>
/// <returns></returns>
[HttpGet("{id}")]
public IEnumerable<KeyValuePair<DateTime, string>> Get(string id, [FromServices]IOnlineUsers onlineUSers)
{
var user = onlineUSers.OnlineUsers.FirstOrDefault(u => u.ConnectionId == id);
return user?.RequestUrls ?? new KeyValuePair<DateTime, string>[0];
}
/// <summary>
/// 登录页面检查调用
/// </summary>
/// <returns>返回真时 启用行为验证码</returns>
[HttpPut]
[AllowAnonymous]
public bool Put()
{
var ip = (Request.HttpContext.Connection.RemoteIpAddress ?? IPAddress.IPv6Loopback).ToString();
if (_loginUsers.TryGetValue(ip, out var user))
{
user.Reset();
user.User.Count++;
return user.User.Count > 2;
}
var loginUser = new LoginUser() { Ip = ip };
_loginUsers.TryAdd(ip, new LoginUserCache(loginUser, () => _loginUsers.TryRemove(ip, out _)));
return false;
}
private static ConcurrentDictionary<string, LoginUserCache> _loginUsers = new ConcurrentDictionary<string, LoginUserCache>();
/// <summary>
///
/// </summary>
private class LoginUser
{
/// <summary>
///
/// </summary>
public string Ip { get; set; }
/// <summary>
///
/// </summary>
public int Count { get; set; }
}
/// <summary>
///
/// </summary>
private class LoginUserCache : IDisposable
{
private Timer dispatcher;
/// <summary>
///
/// </summary>
/// <param name="user"></param>
/// <param name="action"></param>
public LoginUserCache(LoginUser user, Action action)
{
User = user;
dispatcher = new Timer(_ => action(), null, TimeSpan.FromSeconds(30), Timeout.InfiniteTimeSpan);
}
/// <summary>
///
/// </summary>
public LoginUser User { get; set; }
/// <summary>
///
/// </summary>
public void Reset()
{
if (dispatcher != null) dispatcher.Change(TimeSpan.FromSeconds(30), Timeout.InfiniteTimeSpan);
}
#region Impletement IDispose
/// <summary>
///
/// </summary>
/// <param name="disposing"></param>
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (dispatcher != null)
{
dispatcher.Dispose();
dispatcher = null;
}
}
}
/// <summary>
///
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
}
}