修改BUG:在线用户与IP地址统一使用1分钟过期处理 closed #IUUZ3

#Issue
https://gitee.com/LongbowEnterprise/dashboard/issues?id=IUUZ3
#Comment
统一使用Longbow.Cache.AutoExpireCacheEntry类处理
This commit is contained in:
Argo Zhang 2019-03-31 17:21:31 +08:00
parent 87395f0376
commit 68c3ebcd82
7 changed files with 48 additions and 97 deletions

View File

@ -1,8 +1,11 @@
using Bootstrap.DataAccess;
using Longbow.Cache;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
@ -14,10 +17,10 @@ namespace Bootstrap.Admin
/// </summary>
internal class DefaultOnlineUsers : IOnlineUsers
{
private ConcurrentDictionary<string, OnlineUserCache> _onlineUsers = new ConcurrentDictionary<string, OnlineUserCache>();
private ConcurrentDictionary<string, string> _ipLocator = new ConcurrentDictionary<string, string>();
private HttpClient _client;
private IEnumerable<string> _local = new string[] { "::1", "127.0.0.1" };
private readonly ConcurrentDictionary<string, AutoExpireCacheEntry<OnlineUser>> _onlineUsers = new ConcurrentDictionary<string, AutoExpireCacheEntry<OnlineUser>>();
private readonly ConcurrentDictionary<string, AutoExpireCacheEntry<string>> _ipLocator = new ConcurrentDictionary<string, AutoExpireCacheEntry<string>>();
private readonly HttpClient _client;
private readonly IEnumerable<string> _local = new string[] { "::1", "127.0.0.1" };
/// <summary>
///
/// </summary>
@ -33,7 +36,7 @@ namespace Bootstrap.Admin
/// <returns></returns>
public IEnumerable<OnlineUser> OnlineUsers
{
get { return _onlineUsers.Values.Select(v => v.User); }
get { return _onlineUsers.Values.Select(v => v.Value); }
}
/// <summary>
@ -43,7 +46,7 @@ namespace Bootstrap.Admin
/// <param name="addValueFactory"></param>
/// <param name="updateValueFactory"></param>
/// <returns></returns>
public OnlineUserCache AddOrUpdate(string key, Func<string, OnlineUserCache> addValueFactory, Func<string, OnlineUserCache, OnlineUserCache> updateValueFactory) => _onlineUsers.AddOrUpdate(key, addValueFactory, updateValueFactory);
public AutoExpireCacheEntry<OnlineUser> AddOrUpdate(string key, Func<string, AutoExpireCacheEntry<OnlineUser>> addValueFactory, Func<string, AutoExpireCacheEntry<OnlineUser>, AutoExpireCacheEntry<OnlineUser>> updateValueFactory) => _onlineUsers.AddOrUpdate(key, addValueFactory, updateValueFactory);
/// <summary>
///
@ -51,20 +54,20 @@ namespace Bootstrap.Admin
/// <param name="key"></param>
/// <param name="onlineUserCache"></param>
/// <returns></returns>
public bool TryRemove(string key, out OnlineUserCache onlineUserCache) => _onlineUsers.TryRemove(key, out onlineUserCache);
public bool TryRemove(string key, out AutoExpireCacheEntry<OnlineUser> onlineUserCache) => _onlineUsers.TryRemove(key, out onlineUserCache);
/// <summary>
///
/// </summary>
/// <param name="ip"></param>
/// <returns></returns>
public string RetrieveLocaleByIp(string ip = null)
public string RetrieveLocaleByIp(string ip = null) => _ipLocator.GetOrAdd(ip, key => new AutoExpireCacheEntry<string>(IPProxy(key), 1000 * 60, __ => _ipLocator.TryRemove(key, out _))).Value;
private string IPProxy(string ip)
{
var ipSvr = DictHelper.RetrieveLocaleIPSvr();
if (ipSvr.IsNullOrEmpty() || ipSvr.Equals("None", StringComparison.OrdinalIgnoreCase) || ip.IsNullOrEmpty() || _local.Any(p => p == ip)) return "本地连接";
return _ipLocator.GetOrAdd(ip, key =>
{
var ipSvrUrl = DictHelper.RetrieveLocaleIPSvrUrl(ipSvr);
if (ipSvrUrl.IsNullOrEmpty()) return "本地连接";
@ -72,13 +75,23 @@ namespace Bootstrap.Admin
var task = ipSvr == "BaiDuIPSvr" ? RetrieveLocator<BaiDuIPLocator>(url) : RetrieveLocator<JuheIPLocator>(url);
task.Wait();
return task.Result;
});
}
private async Task<string> RetrieveLocator<T>(string url)
{
var result = await _client.GetAsJsonAsync<T>(url);
return result.ToString();
var ret = default(T);
try
{
ret = await _client.GetAsJsonAsync<T>(url);
}
catch (Exception ex)
{
ex.Log(new NameValueCollection()
{
["Url"] = url
});
}
return ret?.ToString();
}
/// <summary>

View File

@ -1,4 +1,5 @@
using System;
using Longbow.Cache;
using System;
using System.Collections.Generic;
namespace Bootstrap.Admin
@ -20,7 +21,7 @@ namespace Bootstrap.Admin
/// <param name="addValueFactory"></param>
/// <param name="updateValueFactory"></param>
/// <returns></returns>
OnlineUserCache AddOrUpdate(string key, Func<string, OnlineUserCache> addValueFactory, Func<string, OnlineUserCache, OnlineUserCache> updateValueFactory);
AutoExpireCacheEntry<OnlineUser> AddOrUpdate(string key, Func<string, AutoExpireCacheEntry<OnlineUser>> addValueFactory, Func<string, AutoExpireCacheEntry<OnlineUser>, AutoExpireCacheEntry<OnlineUser>> updateValueFactory);
/// <summary>
///
@ -28,7 +29,7 @@ namespace Bootstrap.Admin
/// <param name="key"></param>
/// <param name="onlineUserCache"></param>
/// <returns></returns>
bool TryRemove(string key, out OnlineUserCache onlineUserCache);
bool TryRemove(string key, out AutoExpireCacheEntry<OnlineUser> onlineUserCache);
/// <summary>
///

View File

@ -1,63 +0,0 @@
using System;
using System.Threading;
namespace Bootstrap.Admin
{
/// <summary>
///
/// </summary>
public class OnlineUserCache : IDisposable
{
private Timer dispatcher;
/// <summary>
///
/// </summary>
/// <param name="user"></param>
/// <param name="action"></param>
public OnlineUserCache(OnlineUser user, Action action)
{
User = user;
dispatcher = new Timer(_ => action(), null, TimeSpan.FromMinutes(1), Timeout.InfiniteTimeSpan);
}
/// <summary>
///
/// </summary>
public OnlineUser User { get; set; }
/// <summary>
///
/// </summary>
public void Reset()
{
if (dispatcher != null) dispatcher.Change(TimeSpan.FromMinutes(1), 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
}
}

View File

@ -1,5 +1,6 @@
using Bootstrap.Admin;
using Bootstrap.DataAccess;
using Longbow.Cache;
using Longbow.Web;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
@ -27,9 +28,9 @@ namespace Microsoft.AspNetCore.Builder
if (user == null) return;
var onlineUserSvr = context.RequestServices.GetRequiredService<IOnlineUsers>();
var proxy = new Func<OnlineUserCache, Action, OnlineUserCache>((c, action) =>
var proxy = new Func<AutoExpireCacheEntry<OnlineUser>, Action, AutoExpireCacheEntry<OnlineUser>>((c, action) =>
{
var v = c.User;
var v = c.Value;
v.UserName = user.UserName;
v.DisplayName = user.DisplayName;
v.LastAccessTime = DateTime.Now;
@ -50,7 +51,7 @@ namespace Microsoft.AspNetCore.Builder
v.Browser = $"{agent.Browser.Name} {agent.Browser.Version}";
v.OS = $"{agent.OS.Name} {agent.OS.Version}";
v.FirstAccessTime = DateTime.Now;
return proxy(new OnlineUserCache(v, () => onlineUserSvr.TryRemove(key, out _)), null);
return proxy(new AutoExpireCacheEntry<OnlineUser>(v, 1000 * 60, __ => onlineUserSvr.TryRemove(key, out _)), null);
}, (key, v) => proxy(v, () => v.Reset()));
});
await next();

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
@ -12,7 +12,7 @@
<ItemGroup>
<PackageReference Include="Bootstrap.Security.DataAccess" Version="2.1.0" />
<PackageReference Include="Longbow.Cache" Version="2.2.3" />
<PackageReference Include="Longbow.Cache" Version="2.2.4" />
<PackageReference Include="Longbow.Data" Version="2.2.6" />
<PackageReference Include="Longbow.Web" Version="2.2.8" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="2.2.2" />

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
@ -10,7 +10,6 @@
<ItemGroup>
<PackageReference Include="Bootstrap.Security.Mvc" Version="2.2.4" />
<PackageReference Include="Longbow.Cache" Version="2.2.3" />
<PackageReference Include="Longbow.Logging" Version="2.2.6" />
<PackageReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>

View File

@ -15,7 +15,7 @@
<PackageReference Include="Longbow.Data" Version="2.2.6" />
<PackageReference Include="Longbow.Security.Cryptography" Version="1.3.0" />
<PackageReference Include="Longbow.Web" Version="2.2.8" />
<PackageReference Include="Longbow.Cache" Version="2.2.3" />
<PackageReference Include="Longbow.Cache" Version="2.2.4" />
<PackageReference Include="Longbow" Version="2.2.7" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="2.2.2" />
</ItemGroup>