我有一台服务器从许多客户端接收许多对象,并且每次收到一个对象时都会触发ObjectReceived
事件,包括发送了什么的参数。
问题:有一个客户端在我的服务器上遇到请求,但我的服务器总是响应。
我想根据是谁来制定请求。例如,如果我在100秒内从100个不同的客户端收到100个请求,并且每个客户端都提出了不同的请求,我会回复每个提出请求的客户;但是如果我在1秒钟内从2个客户端收到100个请求,并且每个客户端已经完成相同的请求50次,我只回复两次,一次回到客户端A,一次回到客户端B.
在Rx中可以吗?
答案 0 :(得分:2)
是的,一种方法是按客户端ID对请求进行分组,并有选择地应用限制。
说你有这样的事件:
public class MyEvent
{
public int ClientId { get; set; }
public override string ToString()
{
return ClientId.ToString();
}
}
让我们设置慢速和快速客户端:
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);
现在选择性地节流:
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()));
有了这个节流,快速客户端将永远不会得到响应 - Throttle将无限期地抑制他的请求,因为它们距离不到一秒钟。您可以使用其他运算符以不同方式抑制 - 例如Sample
可以在给定的时间间隔内选择一个请求。
您可以应用不同于ClientId的规则并使用Throttle
- 您可以在客户端流上使用DistinctUntilChanged()
来清除重复请求,例如。
答案 1 :(得分:0)
略有不同的问题:Best way to implement request throttling in ASP.NET MVC?
在任何情况下,执行得非常好的典型算法都是:Hierarchical Token bucket。
分层令牌桶(HTB)是更快的替代品 Linux中基于类的排队(CBQ)排队规则。
HTB有助于控制给定的出站带宽的使用 链接。 HTB允许使用单个物理链路来模拟多个 较慢的链接和不同的发送不同类型的流量 模拟链接。在这两种情况下,都必须指定如何划分 物理链接到模拟链接以及如何决定哪个模拟 链接一个给定的数据包将被发送。
换句话说,HTB对限制客户端的下载/上传非常有用 率。因此,有限的客户端无法使总带宽饱和。