我知道客户端 _underscore.js 可以用来限制点击率,但是你如何限制服务器端的调用呢?我想过使用相同的模式,但不幸的是 _throttle 似乎不允许区分 Meteor.userId() 的。
Meteor.methods({
doSomething: function(arg1, arg2){
// how can you throttle this without affecting ALL users
}
);
我知道客户端 _underscore.js 可以用来限制点击率,但是你如何限制服务器端的调用呢?我想过使用相同的模式,但不幸的是 _throttle 似乎不允许区分 Meteor.userId() 的。
Meteor.methods({
doSomething: function(arg1, arg2){
// how can you throttle this without affecting ALL users
}
);
这是一个我已经粗略完成的包 - 但尚未提交给 Atmosphere(等到我熟悉 tinytest 并为它编写单元测试)。
https://github.com/zeroasterisk/Meteor-Throttle
随意使用、扩展、修复和贡献(鼓励拉取请求)
这个概念很简单,它只在服务器上运行(应该只运行)。
你首先需要为你想要限制的东西想出一个唯一的键......
例如:Meteor.userId() + 'my-function-name' + 'whatever'
该系统使用新的 Collection 'throttle' 和一些辅助方法来:
check
、set
和purge
记录。还有一个辅助checkThenSet
方法,实际上是最常见的模式,检查我们是否可以做某事,并设置我们所做的记录。
(用例)如果您的应用程序正在发送电子邮件,您不希望一遍又一遍地发送相同的电子邮件,即使用户触发了它。
// on server
if (!Throttle.checkThenSet(key, allowedCount, expireInSec)) {
throw new Meteor.Error(500, 'You may only send ' + allowedCount + ' emails at a time, wait a while and try again');
}
....
checkThenSet(key, allowedCount, expireInSec)
检查密钥,如果通过,则设置密钥以供将来检查check(key, allowedCount)
检查一个键,如果少于allowedCount
(未过期的)记录,则通过set(key, expireInSec)
设置key的记录,expireInSec
秒后过期,eg: 60
= 1 min in the futurepurge()
过期所有不再在时间范围内的记录(每次检查时自动调用)throttle(key, allowedCount, expireInSec)
-->Throttle.checkThenSet()
throttle-check(key, allowedCount)
-->Throttle.check()
throttle-set(key, expireInSec)
-->Throttle.set()
目前在流星中没有内置支持,但它在路线图上https://trello.com/c/SYcbkS3q/18-dos-hardening-rate-limiting
理论上你可以在这里使用一些选项Throttling method calls to M requests in N seconds但你必须推出自己的解决方案