#node.js #scalability #broadcast
#node.js #масштабируемость #трансляция
Вопрос:
Я программирую Node.js сервер, через который клиенты могут подключаться к серверу /read?id=45
(где идентификатор клиента в этом примере равен 45). Сервер сохраняет соединение в объекте и будет вызывать res.end(message)
его, когда придет сообщение для клиента # 45. В качестве альтернативы, через 60 секунд соединение будет закрыто, и идея заключается в том, что клиент звонит /read
снова.
Соединение сохраняется следующим образом:
var openConn = {};
function handleReadReq(req, res) {
var id = input.returnFromGet(req, 'id'); // fetches the ?id value
// Save the connection to openConn
openConn[id] = new Array();
openConn[id].push(res);
openConn[id].push( setTimeout(function() {
openConn[id][0].end('');
delete openConn[id];
}
}, 60 * 1000) );
}
Если я отправлю сообщение в / bcast, оно будет транслироваться на все соединения в openConn следующим образом:
function doBcast(req, res) {
var message = input.getPost('message'); // akin to input.returnFromGet
var knownClients = 0
var stealOpenConn = openConn; // 'steal' openConn
openConn = {};
for(var client in stealOpenConn) {
clearTimeout(stealOpenConn[client][1]);
stealOpenConn[client][0].end(message);
knownClients;
}
res.end('' knownClients);
}
Это отлично работает! Однако, как только я подключу несколько тысяч клиентов, он начнет работать невероятно медленно. Охват 4000 клиентов таким способом требует в среднем 16 секунд, что неприемлемо.
Есть ли что-нибудь, что я мог бы сделать, чтобы улучшить скорость?
Я пробовал использовать массив вместо объекта, но это ничего не изменило. Работа над openConn
, а не через stealOpenConn
, тоже ничего не улучшает.
Комментарии:
1. Что именно вы рассчитываете, чтобы получить 16 секунд? Цикл for или ?
2. @mscdex
console.log(new Date().getTime())
до и после цикла. Фактически, этоconn.end(message)
(не очистка тайм-аута) занимает большую часть времени (95% или более), а тестовые сообщения были менее 20 символов.