188 lines
6.0 KiB
C#
188 lines
6.0 KiB
C#
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;
|
|
|
|
namespace Bootstrap.Admin
|
|
{
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
internal class DefaultOnlineUsers : IOnlineUsers
|
|
{
|
|
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>
|
|
/// <param name="factory"></param>
|
|
public DefaultOnlineUsers(IHttpClientFactory factory)
|
|
{
|
|
_client = factory.CreateClient(OnlineUsersServicesCollectionExtensions.IPSvrHttpClientName);
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public IEnumerable<OnlineUser> OnlineUsers
|
|
{
|
|
get { return _onlineUsers.Values.Select(v => v.Value); }
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="key"></param>
|
|
/// <param name="addValueFactory"></param>
|
|
/// <param name="updateValueFactory"></param>
|
|
/// <returns></returns>
|
|
public AutoExpireCacheEntry<OnlineUser> AddOrUpdate(string key, Func<string, AutoExpireCacheEntry<OnlineUser>> addValueFactory, Func<string, AutoExpireCacheEntry<OnlineUser>, AutoExpireCacheEntry<OnlineUser>> updateValueFactory) => _onlineUsers.AddOrUpdate(key, addValueFactory, updateValueFactory);
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="key"></param>
|
|
/// <param name="onlineUserCache"></param>
|
|
/// <returns></returns>
|
|
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) => _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 "本地连接";
|
|
|
|
var ipSvrUrl = DictHelper.RetrieveLocaleIPSvrUrl(ipSvr);
|
|
if (ipSvrUrl.IsNullOrEmpty()) return "本地连接";
|
|
|
|
var url = $"{ipSvrUrl}{ip}";
|
|
var task = ipSvr == "BaiDuIPSvr" ? RetrieveLocator<BaiDuIPLocator>(url) : RetrieveLocator<JuheIPLocator>(url);
|
|
task.Wait();
|
|
return task.Result;
|
|
}
|
|
|
|
private async Task<string> RetrieveLocator<T>(string url)
|
|
{
|
|
var ret = default(T);
|
|
try
|
|
{
|
|
ret = await _client.GetAsJsonAsync<T>(url);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ex.Log(new NameValueCollection()
|
|
{
|
|
["Url"] = url
|
|
});
|
|
}
|
|
return ret?.ToString();
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
private class BaiDuIPLocator
|
|
{
|
|
/// <summary>
|
|
/// 详细地址信息
|
|
/// </summary>
|
|
public string Address { get; set; }
|
|
|
|
/// <summary>
|
|
/// 结果状态返回码
|
|
/// </summary>
|
|
public string Status { get; set; }
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override string ToString()
|
|
{
|
|
return Status == "0" ? string.Join(" ", Address.SpanSplit("|").Skip(1).Take(2)) : "XX XX";
|
|
}
|
|
}
|
|
|
|
private class JuheIPLocator
|
|
{
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public string ResultCode { get; set; }
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public string Reason { get; set; }
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public JuheIPLocatorResult Result { get; set; }
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <value></value>
|
|
public int Error_Code { get; set; }
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override string ToString()
|
|
{
|
|
return Error_Code != 0 ? "XX XX" : Result.ToString();
|
|
}
|
|
}
|
|
|
|
private class JuheIPLocatorResult
|
|
{
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public string Country { get; set; }
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public string Province { get; set; }
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public string City { get; set; }
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public string Isp { get; set; }
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override string ToString()
|
|
{
|
|
return Country != "中国" ? $"{Country} {Province} {Isp}" : $"{Province} {City} {Isp}";
|
|
}
|
|
}
|
|
}
|
|
}
|