samedi 3 janvier 2015

Nodejs - prevent socket.io from dropping the frame rates


I'm trying to program some animations in html5 canvas. I need the animations to be reproduced on any other client connected to my server. So what I do is I send the function to be called and the arguments as a string and call eval() on the client side. That way the animation logic needs to be done only on one canvas, while the function calls that actually render things are executed by all clients.


However, my frame rates drop drastically when I do this. I use socket.emit() to send signals to the server which in turn calls socket.broadcast.emit() to send the string to all clients. This is the rendering loop :



var rf = function()
{
// clear background
context.fillStyle = "#000";
context.fillRect(0, 0, width, height);
socket.emit('action', 'clearScreen', "{}");
// mouse position to head towards
var cx = (mousex - width / 2) + (width / 2),
cy = (mousey - height / 2) + (height / 2);

// update all stars
var sat = Floor(Z * 500); // Z range 0.01 -> 0.5
if (sat > 100) sat = 100;
for (var i=0; i<units; i++)
{
var n = stars[i], // the star
xx = n.x / n.z, // star position
yy = n.y / n.z,
e = (1.0 / n.z + 1) * 2; // size i.e. z

if (n.px !== 0)
{
// hsl colour from a sine wave
context.strokeStyle = "hsl(" + ((cycle * i) % 360) + "," + sat + "%,80%)";
context.lineWidth = e;
context.beginPath();
socket.emit('action', 'context.beginPath', "{}");
context.moveTo(xx + cx, yy + cy);
socket.emit('action', 'context.moveTo', "{\"a\": [" + (xx + cx) + "," + (yy + cy) + "]}");
context.lineTo(n.px + cx, n.py + cy);
socket.emit('action', 'context.lineTo', "{\"a\": [" + (n.px + cx) + "," + (n.py + cy) + "]}");
context.stroke();
socket.emit('action', 'context.stroke', "{}");
}

// update star position values with new settings
n.px = xx;
n.py = yy;
n.z -= Z;

// reset when star is out of the view field
if (n.z < Z || n.px > width || n.py > height)
{
// reset star
resetstar(n);
}
}

// colour cycle sinewave rotation
cycle += 0.01;

requestAnimFrame(rf);
};
requestAnimFrame(rf);


The above snippet was taken from here.


Can you suggest ways to prevent the frame rates from dropping? I guess this can be done if socket.emit was non-blocking. Sending strings that reproduces the frame is the lightest way to accomplish what i want. Sending pixels are even more heavy. Sending strings works fine when the frame is easy to draw - for example a simple circle moving up and down renders fine.





Aucun commentaire:

Enregistrer un commentaire