I'm trying to create a nodejs server where I'm running a simple x/y world, which the clients can push/pull data from. If I would do a world-simulation like this on the client side only with box2d or something, I would use the setTimeout function to which would call a step-function. This does not work when I try it in nodejs. The server crashes with the error "RangeError: Maximum call stack size exceeded".
This is my server.js. The world parameter is an instance of a world object that the router can manipulate.
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;
So: how do I run a simulation with nodejs?
The reason you can't call setTimeout in a loop like you are trying to do is because you are creating thousands of timers very quickly (and recursively) which all need to end up on the stack. If you want to use setTimeout, just put it outside of the step_world
function instead of inside of it.
Something like this should work. It will call your step_world function every 1000/30 ms without causing a stack overflow.
function step_world(world,step) {
world.update();
step++;
console.log("updating world: " + step);
}
setTimeout(step_world(world,step),1000/30);
// or setInterval(...)
The other way to test Node is to just make requests to your server. You could do this manually using curl
or using a unit test framework like http://visionmedia.github.com/mocha/.
I read an commented on the other answer but I believe your original idea was right. The problem is you are calling the function in your setTimeout call immediately resulting in infinite recursion.
This happens because you call step_world like this:
step_world(world, step)
Everytime you invoke setTimeout. Try this instead
setTimeout(step_world, 1000/30, world, step)
which calls step_world with the parameters world and step after a dealy. Another way to achieve the same result:
setTimeout(function() {
step_world(world, step);
}, 1000/30);