【问题标题】:nodejs server-side simulationnodejs服务端模拟
【发布时间】:2012-05-06 18:02:59
【问题描述】:

我正在尝试创建一个 nodejs 服务器,在该服务器上运行一个简单的 x/y 世界,客户端可以从中推送/拉取数据。如果我只想在客户端使用 box2d 或其他东西进行这样的世界模拟,我会使用 setTimeout 函数,该函数将调用一个步进函数。当我在 nodejs 中尝试时,这不起作用。服务器崩溃并出现错误“RangeError:超出最大调用堆栈大小”。

这是我的 server.js。 world 参数是路由器可以操作的世界对象的一个​​实例。

var http = require("http");

function start(world, router, handlers) {

function onRequest(request, response) {
    router(world, handlers, request, response);

}

http.createServer(onRequest).listen(8888);
console.log("ServerStarted. Listens to 8888.");

step_world(world,0);
}

function step_world(world,step) {
world.update();
step++;
console.log("updating world: " + step);
step_world(world,step);
//setTimeout(step_world(world,step),1000/30);
}

exports.start = start;

那么:如何使用 nodejs 运行模拟?

【问题讨论】:

    标签: node.js box2d simulation server-side


    【解决方案1】:

    您不能像您尝试那样在循环中调用 setTimeout 的原因是因为您正在非常快速(并且递归地)创建数千个计时器,所有这些计时器都需要在堆栈中结束。如果您想使用 setTimeout,只需将其放在 step_world 函数之外,而不是在其中。

    这样的事情应该可以工作。它将每 1000/30 毫秒调用一次 step_world 函数,而不会导致堆栈溢出。

    function step_world(world,step) {
    world.update();
    step++;
    console.log("updating world: " + step);
    }
    
    setTimeout(step_world(world,step),1000/30);
    // or setInterval(...)
    

    测试 Node 的另一种方法是向您的服务器发出请求。您可以使用curl 或使用像http://visionmedia.github.com/mocha/ 这样的单元测试框架手动执行此操作。

    【讨论】:

    • setInterval 会,但我不相信 setTimeout 会导致多次调用。
    【解决方案2】:

    我阅读了对另一个答案的评论,但我相信您最初的想法是正确的。问题是您在 setTimeout 调用中立即调用该函数,导致无限递归。

    发生这种情况是因为您这样调用 step_world:

    step_world(world, step)
    

    每次调用 setTimeout。试试这个

    setTimeout(step_world, 1000/30, world, step)
    

    它使用参数 world 调用 step_world 并在交易后执行 step。实现相同结果的另一种方法:

    setTimeout(function() {
        step_world(world, step);
    }, 1000/30);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-21
      • 2016-07-08
      • 1970-01-01
      • 2014-10-31
      • 2012-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多