增加功能:增加在线用户统计功能
This commit is contained in:
parent
5ea8022d3c
commit
a4520041c9
|
@ -0,0 +1,23 @@
|
|||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Bootstrap.Admin.Controllers.Api
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class OnlineUsersController : ControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost()]
|
||||
public IEnumerable<OnlineUser> Post([FromServices]IOnlineUsers onlineUSers)
|
||||
{
|
||||
return onlineUSers.OnlineUsers;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Bootstrap.Admin
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
internal class DefaultOnlineUsers : IOnlineUsers
|
||||
{
|
||||
private ConcurrentDictionary<string, OnlineUser> _onlineUsers = new ConcurrentDictionary<string, OnlineUser>();
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<OnlineUser> OnlineUsers
|
||||
{
|
||||
get { return _onlineUsers.Values; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="addValueFactory"></param>
|
||||
/// <param name="updateValueFactory"></param>
|
||||
/// <returns></returns>
|
||||
public OnlineUser AddOrUpdate(string key, Func<string, OnlineUser> addValueFactory, Func<string, OnlineUser, OnlineUser> updateValueFactory) => _onlineUsers.AddOrUpdate(key, addValueFactory, updateValueFactory);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Bootstrap.Admin
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public interface IOnlineUsers
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
IEnumerable<OnlineUser> OnlineUsers { get; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="addValueFactory"></param>
|
||||
/// <param name="updateValueFactory"></param>
|
||||
/// <returns></returns>
|
||||
OnlineUser AddOrUpdate(string key, Func<string, OnlineUser> addValueFactory, Func<string, OnlineUser, OnlineUser> updateValueFactory);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Bootstrap.Admin
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class OnlineUser
|
||||
{
|
||||
private ConcurrentQueue<KeyValuePair<DateTime, string>> _requestUrls;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="ip"></param>
|
||||
/// <param name="userName"></param>
|
||||
/// <param name="method"></param>
|
||||
public OnlineUser(string ip, string userName, string method)
|
||||
{
|
||||
Ip = ip;
|
||||
UserName = userName;
|
||||
Method = method;
|
||||
FirstAccessTime = DateTime.Now;
|
||||
LastAccessTime = DateTime.Now;
|
||||
_requestUrls = new ConcurrentQueue<KeyValuePair<DateTime, string>>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string UserName { get; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public DateTime FirstAccessTime { get; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public DateTime LastAccessTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Method { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Ip { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public IEnumerable<KeyValuePair<DateTime, string>> RequestUrls
|
||||
{
|
||||
get
|
||||
{
|
||||
return _requestUrls.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
public void AddRequestUrl(string url)
|
||||
{
|
||||
_requestUrls.Enqueue(new KeyValuePair<DateTime, string>(DateTime.Now, url));
|
||||
if (_requestUrls.Count > 10)
|
||||
{
|
||||
_requestUrls.TryDequeue(out _);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
using Bootstrap.Admin;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.AspNetCore.Builder
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static class OnlineUsersMiddlewareExtensions
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="builder"></param>
|
||||
/// <returns></returns>
|
||||
public static IApplicationBuilder UseOnlineUsers(this IApplicationBuilder builder) => builder.UseWhen(context => context.Filter(), app => app.Use(async (context, next) =>
|
||||
{
|
||||
await Task.Run(() =>
|
||||
{
|
||||
var onlineUsers = context.RequestServices.GetService<IOnlineUsers>();
|
||||
var clientIp = context.Connection.RemoteIpAddress.ToString();
|
||||
onlineUsers.AddOrUpdate(clientIp, key =>
|
||||
{
|
||||
var ou = new OnlineUser(key, context.User.Identity.Name, context.Request.Method);
|
||||
ou.AddRequestUrl(context.Request.Path);
|
||||
return ou;
|
||||
}, (key, v) =>
|
||||
{
|
||||
v.LastAccessTime = DateTime.Now;
|
||||
v.Method = context.Request.Method;
|
||||
v.AddRequestUrl(context.Request.Path);
|
||||
return v;
|
||||
});
|
||||
});
|
||||
await next();
|
||||
}));
|
||||
|
||||
private static bool Filter(this HttpContext context)
|
||||
{
|
||||
var url = context.Request.Path;
|
||||
return !new string[] { "/api", "/NotiHub", "/swagger" }.Any(r => url.StartsWithSegments(r, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
using Bootstrap.Admin;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static class OnlineUsersServicesCollectionExtensions
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <returns></returns>
|
||||
public static IServiceCollection AddOnlineUsers(this IServiceCollection services)
|
||||
{
|
||||
services.TryAddSingleton<IOnlineUsers, DefaultOnlineUsers>();
|
||||
return services;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -60,6 +60,7 @@ namespace Bootstrap.Admin
|
|||
services.AddConfigurationManager(Configuration);
|
||||
services.AddCacheManager(Configuration);
|
||||
services.AddDbAdapter();
|
||||
services.AddOnlineUsers();
|
||||
var dataProtectionBuilder = services.AddDataProtection(op => op.ApplicationDiscriminator = Configuration["ApplicationDiscriminator"])
|
||||
.SetApplicationName(Configuration["ApplicationName"])
|
||||
.PersistKeysToFileSystem(new DirectoryInfo(Configuration["KeyPath"]));
|
||||
|
@ -125,6 +126,7 @@ namespace Bootstrap.Admin
|
|||
app.UseStaticFiles();
|
||||
app.UseAuthentication();
|
||||
app.UseBootstrapAdminAuthorization(RoleHelper.RetrieveRolesByUserName, RoleHelper.RetrieveRolesByUrl, AppHelper.RetrievesByUserName);
|
||||
app.UseOnlineUsers();
|
||||
app.UseCacheManagerCorsHandler();
|
||||
app.UseSignalR(routes => { routes.MapHub<SignalRHub>("/NotiHub"); });
|
||||
app.UseMvc(routes =>
|
||||
|
|
Loading…
Reference in New Issue