Previous topicNext topic
Help > 开发指南 > API对接 > HttpServer > 事件 >
中间件示例-控制IP访问频率

 

Vb.Net
Dim e As SmHttpRequestEventArgs=Args(0)

'控制IP访问频次
If Not Proj.ExtendedProperties.ContainsKey("IP访问频次") Then
    '如果不存在此数据,则添加
    Dim dic As New Concurrent.ConcurrentDictionary(Of String,List(Of DateTime))
    Proj.ExtendedProperties("IP访问频次")=dic
End If
Dim _requestLogs As Concurrent.ConcurrentDictionary(Of String,List(Of DateTime))=Proj.ExtendedProperties("IP访问频次")
'定义每分钟限制访问频率
Dim maxRequestsPerMinute As Integer = 10
'定义频率限制时间
Dim timeWindow As TimeSpan = TimeSpan.FromMinutes(1)
Dim clientIp As String=e.RemoteAddress
' 获取或添加该 IP 的请求时间记录
Dim requestTimes As List(Of DateTime) = Nothing
If Not _requestLogs.TryGetValue(clientIp, requestTimes) Then
    requestTimes = New List(Of DateTime)()
    _requestLogs(clientIp) = requestTimes
End If
' 清理超出时间窗口的旧记录
Dim currentTime As DateTime = DateTime.Now
requestTimes.RemoveAll(Function(time) currentTime - time > timeWindow)

' 判断是否超过最大请求数
If requestTimes.Count >= maxRequestsPerMinute Then
    Dim obj As New ReturnedObject
    obj.Code=207
    '返回API执行失败的结果
    obj.Successed=False
    '可以根据需要将相应的信息返回给客户端
    obj.Message="访问频率超过限制"
    e.SendObject(obj)
    
    Return False
End If

' 记录本次请求时间
requestTimes.Add(currentTime)

'中间件如果不想后续程序的执行的话,则必须返回True
Return True

C#
SmHttpRequestEventArgs e = (SmHttpRequestEventArgs)Args[0];

// 控制IP访问频次
if (!Proj.ExtendedProperties.ContainsKey("IP访问频次"))
{
    // 如果不存在此数据,则添加
    var dic = new ConcurrentDictionary<string, List<DateTime>>();
    Proj.ExtendedProperties["IP访问频次"] = dic;
}

var _requestLogs = (ConcurrentDictionary<string, List<DateTime>>)Proj.ExtendedProperties["IP访问频次"];
// 定义每分钟限制访问频率
int maxRequestsPerMinute = 10;
// 定义频率限制时间
TimeSpan timeWindow = TimeSpan.FromMinutes(1);
string clientIp = e.RemoteAddress;

// 获取或添加该 IP 的请求时间记录
List<DateTime> requestTimes=null;
if (!_requestLogs.TryGetValue(clientIp, out requestTimes))
{
    requestTimes = new List<DateTime>();
    _requestLogs[clientIp] = requestTimes;
}

// 清理超出时间窗口的旧记录
DateTime currentTime = DateTime.Now;
requestTimes.RemoveAll(time => currentTime - time > timeWindow);

// 判断是否超过最大请求数
if (requestTimes.Count >= maxRequestsPerMinute)
{
    ReturnedObject obj = new ReturnedObject();
    obj.Code = 207;
    // 返回API执行失败的结果
    obj.Successed = false;
    // 可以根据需要将相应的信息返回给客户端
    obj.Message ="访问频率超过限制";
    
    e.SendObject(obj);
    return false;
}

// 记录本次请求时间
requestTimes.Add(currentTime);

// 中间件如果不想后续程序的执行的话,则必须返回True
return true;