C# 如何使用反应式扩展来限制客户端请求

C# 如何使用反应式扩展来限制客户端请求,c#,.net,system.reactive,C#,.net,System.reactive,我有一个服务器,它从许多客户端接收许多对象,每次接收对象时都会触发ObjectReceived事件,包括发送内容的参数 问题:有一个客户端用请求骚扰我的服务器,但我的服务器总是响应 我想根据谁提出的请求限制请求。例如,如果我在1秒内收到100个来自100个不同客户的请求,并且每个客户都提出了不同的请求,那么我会响应每个提出请求的客户;但是,如果我在1秒内收到来自两个客户端的100个请求,并且每个客户端都做了50次相同的请求,那么我只响应两次,一次响应客户端A,一次响应客户端B 在Rx中可能吗?是

我有一个服务器,它从许多客户端接收许多对象,每次接收对象时都会触发
ObjectReceived
事件,包括发送内容的参数

问题:有一个客户端用请求骚扰我的服务器,但我的服务器总是响应

我想根据谁提出的请求限制请求。例如,如果我在1秒内收到100个来自100个不同客户的请求,并且每个客户都提出了不同的请求,那么我会响应每个提出请求的客户;但是,如果我在1秒内收到来自两个客户端的100个请求,并且每个客户端都做了50次相同的请求,那么我只响应两次,一次响应客户端A,一次响应客户端B


在Rx中可能吗?

是的,一种方法是按客户端id对请求进行分组,并有选择地应用限制

假设你有过这样的活动:

public class MyEvent
{
    public int ClientId { get; set; }

    public override string ToString()
    {
        return ClientId.ToString();
    }
}
var throttled = all.GroupBy(x => x.ClientId).Select(
    // apply the throttle here, this could even test the key
    // property to apply different throttles to different clients
    x => x.Throttle(TimeSpan.FromSeconds(1)))
    .SelectMany(x => x);
让我们设置慢速和快速客户端:

var slow = Observable.Interval(TimeSpan.FromSeconds(2))
                     .Select(_ => new MyEvent { ClientId = 1 });

var fast = Observable.Interval(TimeSpan.FromSeconds(0.5))
                     .Select(_ => new MyEvent { ClientId = 2 });    

var all = slow.Merge(fast);
现在有选择地如下:

public class MyEvent
{
    public int ClientId { get; set; }

    public override string ToString()
    {
        return ClientId.ToString();
    }
}
var throttled = all.GroupBy(x => x.ClientId).Select(
    // apply the throttle here, this could even test the key
    // property to apply different throttles to different clients
    x => x.Throttle(TimeSpan.FromSeconds(1)))
    .SelectMany(x => x);
并测试它:

throttled.Subscribe(x => Console.WriteLine(x.ToString())); 
有了这个节流阀,快速客户端将永远不会得到响应——节流阀将无限期地抑制他的请求,因为它们之间的间隔不到一秒钟。您可以使用其他运算符以不同的方式抑制,例如,
Sample
可以在给定的时间间隔内选择单个请求

在你的问题编辑之后
您可以应用不同于“按客户端ID”的规则,并使用
节流阀
——例如,您可以在客户端流上使用
DistinctUntilChanged()
来删除重复的请求。

稍有不同的问题:

在任何情况下,性能非常好的典型算法是:

分层令牌桶(HTB)是对 Linux中基于类的排队(CBQ)排队规程

HTB有助于控制给定网络上出站带宽的使用 链接HTB允许使用一个物理链路来模拟多个物理链路 较慢的链接,并在不同的网络上发送不同种类的流量 模拟链接。在这两种情况下,都必须指定如何划分 物理链接到模拟链接以及如何决定哪个模拟链接 一个给定的数据包将被发送的链路

换句话说,HTB对于限制客户端的下载/上传非常有用 比率。因此,有限的客户端不能使总带宽饱和


可能是。我们缺少一些信息。假设您希望响应1个请求/秒,但恼人的客户端以100/秒的速度发送请求。其余的99块你怎么处理?让他们排队?当队列长度为1000000个条目时会发生什么情况?内存不足?拒绝他们?如何拒绝它们?你是对的,编辑你面临的情况被称为拒绝服务攻击。安全性是应用程序的一个方面,我认为您应该在尽可能低的层中修复它。看看这个,然后。另外,请查看最后一个链接的评论,因为有两个改进建议。我当然同意最低级别的观点——也就是说,我必须制定政策,防止非恶意地过度使用具有复杂业务域规则的API。然而,这些天来,通过API托管产品(如apigee、3scale等)越来越多地提供这类服务。就连Azure现在也有了。嗨,Throttle和Sample实际上延迟了我订阅的执行。有没有一种方法可以立即响应第一个请求,并且在一定时间内不接受相同类型的请求?@sam试试这个。我为这个老问题添加了一个新的答案,我认为它很好地解决了所有问题: