web流量控制简化处理类
该类可用于HttpListener类的web端或asp.net web服务端的访问控制,类代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Utility;
namespace My.BLL.Throttle
{
/// <summary>
/// 访问次数检验类
/// 自动清理过期的用户数据不及时,处理不合理
/// </summary>
public class ThrottlingHandler
{
private static IThrottleStore _store;
private static TimeSpan _period;
private static int _maxRequests;
static readonly Log Log = new Log("Bll");
static ThrottlingHandler()
{
_store = new InMemoryThrottleStore();
_period = TimeSpan.FromSeconds(60);
}
/// <summary>
/// 设置1分钟内用户的最大访问次数
/// </summary>
/// <param name="maxRequests"></param>
public static void SetMaxReuest(int maxRequests)
{
_maxRequests = maxRequests;
}
/// <summary>
/// 校验用户1分钟内是否超过最大访问次数限制
/// </summary>
/// <param name="identifier">用户标识符</param>
/// <returns></returns>
public static bool IsOverVisitLimit(string identifier)
{
//条目大于5000时清除所有数据,这里的处理不当,先将就这么处理,应定时检测过期的条目,清除过期的
if (_store.GetCount() > 5000)
{
_store.Clear();
}
ThrottleEntry entry = null;
if (_store.TryGetValue(identifier, out entry))
{
if (entry.PeriodStart + _period < DateTime.UtcNow)
{
_store.Rollover(identifier);
}
}
_store.IncrementRequests(identifier);
if (!_store.TryGetValue(identifier, out entry))
{
return false;
}
if (entry.Requests > _maxRequests)
{
Log.Info(identifier + " 访问次数超限 " + _maxRequests.ToString());
return true;
}
return false;
}
}
}
该类内部调用的类参见
调用如下:
BLL.Throttle.ThrottlingHandler.SetMaxReuest(Global.ThrottleMaxRequestTimes);
if (Global.IsEnableThrottle == "1")
{
var isOverVisit = BLL.Throttle.ThrottlingHandler.IsOverVisitLimit(ip);
if (isOverVisit)
{
// 构造回应内容
string responseString
= "访问太频繁了";
// 设置回应头部内容,长度,编码
response.ContentLength64
= Encoding.UTF8.GetByteCount(responseString);
response.ContentType = "text/html; charset=UTF-8";
// 输出回应内容
Stream output2 = response.OutputStream;
StreamWriter writer = new StreamWriter(output2);
writer.Write(responseString);
// 必须关闭输出流
writer.Close();
return;
}
}
--- end ---