2013-08-14 3 views
1

Я использую socket.io для отправки пакетов через websockets. Кажется, они время от времени исчезают. Поэтому я должен реализовать какую-то систему подтверждения. Моя идея заключалась в немедленном ответе на пакет с ACK-пакетом. Если сервер не получит этот ACK-пакет в течение заданного времени, он повторно отправит его (до 3 раз, затем отключит сокет).NodeJs: Как обрабатывать очень большое количество таймеров?

Моя первая мысль состояла в том, чтобы запустить таймер (setTimeout) после отправки пакета. если происходит время-событие, пакет должен быть отправлен снова. Если ACK придет, тайм-аут будет удален. Довольно легко и коротко.

var io = require('socket.io').listen(80); 

// ... connection handling ... 

function sendData(someData, socket) { 
    // TODO: Some kind of counter to stop after 3 tries. 
    socket.emit("someEvent", someData); 
    var timeout = setTimeout(function(){ sendData(someData, socket); }, 2000); 
    socket.on("ack", function(){ 
    // Everything went ok. 
    clearTimeout(timeout); 
    }); 
} 

Но у меня будут клиенты 1k-3k, связанные с большим количеством трафика. Я не могу себе представить, что 10k таймеров, работающих в то же время, можно выполнить с помощью NodeJS. Еще хуже: Я читал, что NodeJS не будет запускать событие, если на это нет времени.

Как реализовать хорошую рабочую и эффективную систему подтверждения пакетов?

+0

Michael Мне интересно, если вы нашли решение этой проблемы? У меня есть аналогичная проблема здесь http://stackoverflow.com/questions/37234481/handling-timers-for-many-users-in-nodejs –

+0

Действительно у меня есть. Избавьтесь от socket.io - у него много проблем, которые уже не решены. Сейчас я использую sockjs для всех своих проектов - более стабильным, но менее удобным. – Michael

ответ

1

Если socket.io не достаточно надежный для вас, вы можете рассмотреть возможность внедрения собственного интерфейса websocket вместо добавления слоя поверх socket.io. Но чтобы ответить на ваш вопрос, я не думаю, что запуск 10k таймеров будет большим делом. Например, следующий код побежал в возрасте до 3-х секунд для меня и распечатан ожидаемого результата 100000:

var x = 0; 
for (var i = 0; i < 100000; i++) { 
    setTimeout(function() { x++; }, 1000); 
} 

setTimeout(function() { console.log(x); }, 2000); 

Там на самом деле не так много накладных расходов для тайма-аута; он по существу просто попадает в очередь, пока не пришло время его выполнить.

+1

Звучит неплохо. Но ваш процесс ничего не делает. Мой процесс занят другими вещами. И я читаю, что стрельба по таймеру выполняется только при наличии ресурсов. Отсутствующие события таймера, похоже, являются общими. Тем не менее: Спасибо за ваш ответ! – Michael

0

Я прочитал, что NodeJS не будет запускать событие, если на это нет времени.

Это немного преувеличение, таймеры node.js являются надежными. Таймер, установленный setTimeout будет огонь в какой-то момент. Это может быть отложено, если процесс занят в точное время, но вызов будет вызван в конце концов.

Цитируется Node.js docs for setTimeout:

обратного вызова, скорее всего, не будет вызываться в точно задержать миллисекунды. Node.js не дает никаких гарантий относительно точного времени срабатывания обратных вызовов или их заказа. Обратный вызов будет вызван как можно ближе к указанному времени.