增加功能:增加在线用户统计功能
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.AddConfigurationManager(Configuration);
|
||||||
services.AddCacheManager(Configuration);
|
services.AddCacheManager(Configuration);
|
||||||
services.AddDbAdapter();
|
services.AddDbAdapter();
|
||||||
|
services.AddOnlineUsers();
|
||||||
var dataProtectionBuilder = services.AddDataProtection(op => op.ApplicationDiscriminator = Configuration["ApplicationDiscriminator"])
|
var dataProtectionBuilder = services.AddDataProtection(op => op.ApplicationDiscriminator = Configuration["ApplicationDiscriminator"])
|
||||||
.SetApplicationName(Configuration["ApplicationName"])
|
.SetApplicationName(Configuration["ApplicationName"])
|
||||||
.PersistKeysToFileSystem(new DirectoryInfo(Configuration["KeyPath"]));
|
.PersistKeysToFileSystem(new DirectoryInfo(Configuration["KeyPath"]));
|
||||||
|
@ -125,6 +126,7 @@ namespace Bootstrap.Admin
|
||||||
app.UseStaticFiles();
|
app.UseStaticFiles();
|
||||||
app.UseAuthentication();
|
app.UseAuthentication();
|
||||||
app.UseBootstrapAdminAuthorization(RoleHelper.RetrieveRolesByUserName, RoleHelper.RetrieveRolesByUrl, AppHelper.RetrievesByUserName);
|
app.UseBootstrapAdminAuthorization(RoleHelper.RetrieveRolesByUserName, RoleHelper.RetrieveRolesByUrl, AppHelper.RetrievesByUserName);
|
||||||
|
app.UseOnlineUsers();
|
||||||
app.UseCacheManagerCorsHandler();
|
app.UseCacheManagerCorsHandler();
|
||||||
app.UseSignalR(routes => { routes.MapHub<SignalRHub>("/NotiHub"); });
|
app.UseSignalR(routes => { routes.MapHub<SignalRHub>("/NotiHub"); });
|
||||||
app.UseMvc(routes =>
|
app.UseMvc(routes =>
|
||||||
|
|
Loading…
Reference in New Issue