using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Ropin.Core.Common;
using System.Threading;
namespace Ropin.Core.Extensions
{
[AttributeUsage(AttributeTargets.Method, Inherited = true)]
///
/// 限制多出频繁请求
///
///
/// api request idempotence
///
public class HttpIdempotentAttribute : Attribute, IAsyncResourceFilter
{
static HttpIdempotentAttribute()
{
var thread = new Thread(() =>
{
while (true)
{
var hashtableDatas = HashTable.Where(x => DateTime.Now > x.Value.Time).ToList();
if (hashtableDatas.Any())
{
foreach (var hashtableData in hashtableDatas)
{
HashTable.Remove(hashtableData.Key);
}
}
else
{
System.Threading.Thread.Sleep(2000);
}
}
});
thread.IsBackground = true;
thread.Start();
}
///
/// http request parameter code collect
///
private static readonly Dictionary HashTable = new();
///
/// http request parameter code
///
public int _httpHasCode;
///
/// waiting for the last request , default value:1000
///
public double WaitMillisecond { get; set; } = 1000;
///
/// result cache Millisecond , default value:1000
///
public double CacheMillisecond { get; set; } = 1000;
///
/// interceptor
///
///
///
///
public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next)
{
await this.SetHttpParameterHasCode(context.HttpContext);
if (HashTable.ContainsKey(_httpHasCode))
{
var hashtableData = (HashtableData)HashTable[_httpHasCode];
if (hashtableData != null)
{
if (DateTime.Now < hashtableData.Time)
{
context.Result = hashtableData.Value;
return;
}
else if (DateTime.Now > hashtableData.Time)
{
HashTable.Remove(_httpHasCode);
}
else if (hashtableData.Value == null)
{
context.Result = new ContentResult()
{
Content = "正在执行..."
};
//context.Result = new ObjectResult("正在执行...")
//{
// StatusCode = StatusCodes.Status500InternalServerError
//};
return;
}
}
}
HashTable.Add(_httpHasCode, new HashtableData(DateTime.Now.AddMilliseconds(WaitMillisecond), null));
try
{
var netResult = await next();
if (HashTable.ContainsKey(_httpHasCode))
{
var hashtableData = (HashtableData)HashTable[_httpHasCode];
if (hashtableData != null)
{
hashtableData.Value = (IActionResult)netResult.Result;
hashtableData.Time = DateTime.Now.AddMilliseconds(CacheMillisecond);
}
}
}
catch (Exception ex)
{
HashTable.Remove(_httpHasCode);
}
}
///
/// get http request parameter code
///
///
private async Task SetHttpParameterHasCode(HttpContext httpContext)
{
object readFromJson = null;
try
{
if (httpContext.Request.Method != "GET")
{
//readFromJson = await httpContext.Request.ReadFromJsonAsync