JavaScript: использование очереди для сетевого общения
Я работаю над проектом, в котором клиент должен иметь возможность общаться с сервером через WebSockets. Начиная с приложения, которое мы разрабатываем так, чтобы оно было очень отзывчивым на пользовательский ввод, мы решили позволить WebWorker выполнять всю связь по сети, чтобы медленное соединение не могло прерывать графический интерфейс. Это работает отлично до сих пор.
Теперь мы подумали об оптимизации, которая будет необходима, если сеть работает медленно и количество отправляемых сообщений велико. Поскольку большинство из этих сообщений будут только для синхронизации пользовательского интерфейса некоторых других клиентов, мы можем отбросить некоторые из них при необходимости. Но для этого нам нужна возможность выявлять ситуации, когда есть заторы.
Мы придумали идею очереди: каждое отправляемое сообщение помещается в очередь, и WebWorker не делает ничего, кроме постоянной итерации по очереди и отправки всех найденных там сообщений. После этого мы можем позволить Рабочему действовать по-другому, если в очереди есть определенное количество элементов (т.е. сообщения отправляются слишком медленно). Идея проста и понятна, однако реализация, похоже, не такова.
var ws;
var queue = new Array();
function processMessageQueue() {
while(true)
if(queue.length > 0) ws.send(queue.shift());
}
self.addEventListener('message', function(e) {
var msg = e.data;
switch(msg.type) {
case 'SEND':
queue.push(JSON.stringify(msg));
break;
case 'CREATE_WS':
ws = new WebSocket(msg.wsurl);
ws.onmessage = function(e) {
self.postMessage(JSON.parse(e.data));
}
processMessageQueue();
}
}, false);
Как вы можете видеть, рабочий создает WebSocket, как только получает сообщение для этого. Затем он выполняет функцию processMessageQueue(), которая является циклом, который постоянно очищает очередь, отправляя свои данные через WebSocket. Теперь моя проблема в том, что, похоже, нет возможности помещать сообщения в очередь. Это должно произойти, когда приходит сообщение типа "ОТПРАВИТЬ", но это не может сделать, поскольку работник слишком занят, чтобы обрабатывать какие-либо события. Таким образом, он может либо проходить по очереди, либо отправлять сообщения, но не оба.
Что мне нужно, так это способ как-то отправить данные в эту очередь. Если это не легко возможно, я хотел бы знать, может ли кто-нибудь придумать другой способ узнать, когда сообщения приходят быстрее, чем они отправляются. Есть намеки?
Заранее спасибо!
1 ответ
Вы должны дать работнику время для обработки события onmessage. дела while(true)
займет все время обработки и не позволит выполнять какие-либо события.
Вы можете, например, изменить его на
function processMessageQueue() {
if(queue.length > 0) ws.send(queue.shift());
setTimeout(processMessageQueue, 50);
}