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
}
}
}