在我的 Meteor 应用程序中实现基于回合的多人游戏服务器,客户端通过发布/订阅接收游戏状态,并可以调用 Meteor 方法 sendTurn 将回合数据发送到服务器(他们不能直接更新游戏状态集合) .
var endRound = function(gameRound) {
// check if gameRound has already ended /
// if round results have already been determined
// --> yes:
do nothing
// --> no:
// determine round results
// update collection
// create next gameRound
};
Meteor.methods({
sendTurn: function(turnParams) {
// find gameRound data
// validate turnParams against gameRound
// store turn (update "gameRound" collection object)
// have all clients sent in turns for this round?
// yes --> call "endRound"
// no --> wait for other clients to send turns
}
});
为了实现时间限制,我想等待一定时间(让客户有时间调用 sendTurn ),然后确定回合结果 - 但前提是回合结果尚未在 sendTurn 中确定。
我应该如何在服务器上实现这个时间限制?
我天真的实现方法是调用 Meteor.setTimeout(endRound, <roundTimeLimit>) 。
问题:
并发性如何?我假设我应该在 sendTurn 和 endRound (?) 中同步更新集合(没有回调),但这是否足以消除竞争条件? (阅读关于同步数据库操作也产生的 this SO question 已接受答案的第 4 条评论,我对此表示怀疑)
在这方面,“每个请求”在我的上下文中的 Meteor docs 中是什么意思(由客户端方法调用和/或在服务器 endRound 中调用的函数 setTimeout)?
In Meteor, your server code runs in a single thread per request, not in the asynchronous callback style typical of Node.
在多服务器/集群环境中,这(如何)工作?
最佳答案
好问题,它比看起来更棘手。首先,我想指出,我已经在以下存储库中针对这个确切问题实现了解决方案:
https://github.com/ldworkin/meteor-prisoners-dilemma https://github.com/HarvardEconCS/turkserver-meteor
总而言之,问题基本上具有以下性质:
sendTurn)endRoundendRoundendRound 无论客户端做什么,每轮都必须恰好执行一次现在,考虑我们必须处理的 Meteor 的属性:
this.unblock())。以下方法等待第一个。这意味着每当一个方法调用通过一个生成操作时,Node 或数据库中的值就会改变。这可能会导致以下潜在的竞争条件(这些只是我已经修复的,但可能还有其他的):
sendTurn。两者都调用一个 yielding 操作来存储 turn 数据。然后这两种方法检查是否有 2 个玩家轮到他们发送,找到肯定的,然后 endRound 运行两次。sendTurn。在这种情况下,endRound 被超时和播放器方法调用,导致再次运行两次。endRound 永远不会被调用。您可以通过多种方式解决这个问题,在 Node 中同步或在数据库中同步。
endRound 代码移到方法调用本身之外,使用其他东西来触发它。这是我采用的方法,可确保只有计时器或最终玩家触发回合结束,而不是两者都触发(有关使用 observeChanges 的实现,请参阅 here)。在集群环境中,您将不得不仅使用数据库进行同步,可能使用条件更新操作和原子运算符。类似于以下内容:
var currentVal;
while(true) {
currentVal = Foo.findOne(id).val; // yields
if( Foo.update({_id: id, val: currentVal}, {$inc: {val: 1}}) > 0 ) {
// Operation went as expected
// (your code here, e.g. endRound)
break;
}
else {
// Race condition detected, try again
}
}
上述方法很原始,可能会导致高负载下数据库性能不佳;它也不处理计时器,但我相信通过一些思考您可以弄清楚如何扩展它以更好地工作。
您可能还想看到这个 timers code对于其他一些想法。一旦我有时间,我将把它扩展到你描述的完整设置。
关于node.js - Meteor.setTimeout 和 Meteor.methods 之间的并发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32987510/
我好像记得Lua有类似Ruby的method_missing的东西。还是我记错了? 最佳答案 表的metatable的__index和__newindex可以用于与Ruby的method_missing相同的效果。 关于ruby-难道Lua没有和Ruby的method_missing相媲美的东西吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/7732154/
我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此
让我们计算MRI范围内的类别:defcount_classesObjectSpace.count_objects[:T_CLASS]endk=count_classes用类方法定义类:classAdefself.foonilendend然后运行:putscount_classes-k#=>3请解释一下,为什么是三个? 最佳答案 查看MRI代码,每次你创建一个Class时,在Ruby中它是Class类型的对象,ruby会自动为这个新类创建“元类”类,这是另一个单例类型的Class对象。C函数调用(class.c)是:rb_define
似乎无法为此找到有效的答案。我正在阅读Rails教程的第10章第10.1.2节,但似乎无法使邮件程序预览正常工作。我发现处理错误的所有答案都与教程的不同部分相关,我假设我犯的错误正盯着我的脸。我已经完成并将教程中的代码复制/粘贴到相关文件中,但到目前为止,我还看不出我输入的内容与教程中的内容有什么区别。到目前为止,建议是在函数定义中添加或删除参数user,但这并没有解决问题。触发错误的url是http://localhost:3000/rails/mailers/user_mailer/account_activation.http://localhost:3000/rails/mai
在Cooper的书BeginningRuby中,第166页有一个我无法重现的示例。classSongincludeComparableattr_accessor:lengthdef(other)@lengthother.lengthenddefinitialize(song_name,length)@song_name=song_name@length=lengthendenda=Song.new('Rockaroundtheclock',143)b=Song.new('BohemianRhapsody',544)c=Song.new('MinuteWaltz',60)a.betwee
我正在检查一个Rails项目。在ERubyHTML模板页面上,我看到了这样几行:我不明白为什么不这样写:在这种情况下,||=和ifnil?有什么区别? 最佳答案 在这种特殊情况下没有区别,但可能是出于习惯。每当我看到nil?被使用时,它几乎总是使用不当。在Ruby中,很少有东西在逻辑上是假的,只有文字false和nil是。这意味着像if(!x.nil?)这样的代码几乎总是更好地表示为if(x)除非期望x可能是文字false。我会将其切换为||=false,因为它具有相同的结果,但这在很大程度上取决于偏好。唯一的缺点是赋值会在每次运行
给定以下方法:defsome_method:valueend以下语句按我的预期工作:some_method||:other#=>:valuex=some_method||:other#=>:value但是下面语句的行为让我感到困惑:some_method=some_method||:other#=>:other它按预期创建了一个名为some_method的局部变量,随后对some_method的调用返回该局部变量的值。但为什么它分配:other而不是:value呢?我知道这可能不是一件明智的事情,并且可以看出它可能有多么模棱两可,但我认为应该在考虑作业之前评估作业的右侧...我已经在R
📢博客主页:https://blog.csdn.net/weixin_43197380📢欢迎点赞👍收藏⭐留言📝如有错误敬请指正!📢本文由Loewen丶原创,首发于CSDN,转载注明出处🙉📢现在的付出,都会是一种沉淀,只为让你成为更好的人✨文章预览:一.分辨率(Resolution)1、工业相机的分辨率是如何定义的?2、工业相机的分辨率是如何选择的?二.精度(Accuracy)1、像素精度(PixelAccuracy)2、定位精度和重复定位精度(RepeatPrecision)三.公差(Tolerance)四.课后作业(Post-ClassExercises)视觉行业的初学者,甚至是做了1~2年
我正在尝试在配备ARMv7处理器的SynologyDS215j上安装ruby2.2.4或2.3.0。我用了optware-ng安装gcc、make、openssl、openssl-dev和zlib。我根据README中的说明安装了rbenv(版本1.0.0-19-g29b4da7)和ruby-build插件。.这些是随optware-ng安装的软件包及其版本binutils-2.25.1-1gcc-5.3.0-6gconv-modules-2.21-3glibc-opt-2.21-4libc-dev-2.21-1libgmp-6.0.0a-1libmpc-1.0.2-1libm
我正在使用带有Rails的Devise,我想添加一个方法“getAllComments”,所以我这样写:classUser在我的Controller中:defdashboard@user=current_user@comments=@user.getAllComments();end当我访问我的url时,我得到了undefinedmethod`getAllComments'for#我做错了什么?谢谢 最佳答案 因为getAllComments是一个类方法,而您正试图将其作为实例方法访问。您要么需要访问它:User.getAllCom