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 { /// /// 在线用户接口 /// [Route("api/[controller]")] [ApiController] public class OnlineUsersController : ControllerBase { /// /// 获取所有在线用户数据 /// /// [HttpGet()] public IEnumerable Get([FromServices]IOnlineUsers onlineUSers) { return onlineUSers.OnlineUsers.OrderByDescending(u => u.LastAccessTime); } /// /// 获取指定会话的在线用户请求地址明细数据 /// /// /// /// [HttpGet("{id}")] public IEnumerable> Get(string id, [FromServices]IOnlineUsers onlineUSers) { var user = onlineUSers.OnlineUsers.FirstOrDefault(u => u.ConnectionId == id); return user?.RequestUrls ?? new KeyValuePair[0]; } /// /// 登录页面检查调用 /// /// 返回真时 启用行为验证码 [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 _loginUsers = new ConcurrentDictionary(); /// /// /// private class LoginUser { /// /// /// public string Ip { get; set; } /// /// /// public int Count { get; set; } } /// /// /// private class LoginUserCache : IDisposable { private Timer dispatcher; /// /// /// /// /// public LoginUserCache(LoginUser user, Action action) { User = user; dispatcher = new Timer(_ => action(), null, TimeSpan.FromSeconds(30), Timeout.InfiniteTimeSpan); } /// /// /// public LoginUser User { get; set; } /// /// /// public void Reset() { if (dispatcher != null) dispatcher.Change(TimeSpan.FromSeconds(30), Timeout.InfiniteTimeSpan); } #region Impletement IDispose /// /// /// /// protected virtual void Dispose(bool disposing) { if (disposing) { if (dispatcher != null) { dispatcher.Dispose(); dispatcher = null; } } } /// /// /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } #endregion } } }