Skip to content

Instantly share code, notes, and snippets.

@netgusto
Last active February 5, 2022 01:24
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save netgusto/0920eda110121eb7fdb382345c7db5d2 to your computer and use it in GitHub Desktop.
Save netgusto/0920eda110121eb7fdb382345c7db5d2 to your computer and use it in GitHub Desktop.
WebSocket/Node response time & latency (localhost loop)

Evaluate websocket/Node response time for 100 clients triggered simultaneously every second.

$ npm install
$ node wsperf.js

# with socket.io debug
$ DEBUG=socket.io* node wsperf.js

Why so slow ? I was kind of expecting the connections to be handled in parallel, but it seems they're in fact processed sequentially by node. Could that be properly parallelized somehow ?

Description

What: Node server asking 100 clients to update once per second via websocket on a localhost loop.

Context: Server maintaining state for remote clients, clients issuing operations to alter state (some kind of remote game loop).

Mechanics:

  1. Server broadcasts update
  2. Every client (100 clients) queries state on server via emit api
  3. Server handles api requests and answers clients with api response (dummy data)
  4. Client processes state, generates a state update operation, and emits update to the server (dummy operation)
  5. Server aggregates operation to state (dummy operation)
{
"dependencies": {
"performance-now": "^2.1.0",
"socket.io-client": "^1.7.3",
"socketio": "^1.0.0"
}
}
const now = require("performance-now");
const socketio = require("socket.io");
const socketioclient = require("socket.io-client");
const nbclients = 100;
const server = new Server();
const starts = [];
for(let k = 0; k < nbclients; k++) {
starts.push((new Client()).start());
}
Promise
.all(starts)
.then(console.log('All clients started; running game loop.'))
.then(function() {
setInterval(function() {
server.socket.sockets.emit('update', now());
}, 1000);
})
.catch(console.error.bind(console));
/* ***************************************************************************/
/* Implementation */
/* ***************************************************************************/
function Server() {
this.clients = [];
this.socket = socketio();
this.socket.on('connection', clientsocket => {
const clientid = clientsocket.id;
this.clients.push({
id: clientid,
socket: clientsocket
});
clientsocket.on('api', function(fn) {
fn(['api', 'data', 'for', clientid]);
});
clientsocket.on('update', function(data, fn) {
console.log('NEW DATA', 'Took:' + (now() - data.start).toFixed(3) + 'ms', JSON.stringify(data));
fn();
});
});
this.socket.listen(3000);
}
function Client() {
this.socket = null;
this.start = function() {
this.socket = socketioclient('ws://127.0.0.1:3000');
return (new Promise((resolve, reject) => {
this.socket.on('connect', () => {
resolve();
});
this.socket.on('update', start => {
this.update(start);
});
})).catch(console.error.bind(console));
};
this.update = function(start) {
if(!this.socket.connected) return Promise.resolve({});
return (new Promise((resolve, reject) => {
this.socket.emit('api', data => {
const operation = { move: { x: Math.random(), y: Math.random() } , "apimessage": data.join(' '), start: start };
this.socket.emit('update', operation, function() {
resolve();
})
});
})).catch(console.error.bind(console));
}
}
@midnightcodr
Copy link

Maybe you can give ws a try? I wrote a slim down version of your test: https://gist.github.com/midnightcodr/c6f83e52a642da1189de4d58881fe01c

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment