我正在一个项目中,客户端必须能够通过WebSockets与服务器进行通信。由于我们开发的应用程序对用户输入具有很高的响应速度,因此我们决定让WebWorker通过网络进行所有通信,以使缓慢的连接不会中断GUI。到目前为止,一切正常。
现在我们考虑优化,如果网络速度慢并且要发送的消息量很大,则必须进行优化。由于这些消息大多数将仅用于同步其他客户端用户界面,因此如有必要,我们可以删除其中的一些消息。但是要做到这一点,我们需要有可能在拥塞时检测情况。
我们想到了队列的概念:将要发送的每条消息都放入队列中,WebWorker除了在队列上进行永久迭代并发送所有在该队列中找到的消息外,不执行其他任何操作。这样一来,如果队列中有一定数量的元素(即消息发送速度太慢),我们以后可以让Worker采取不同的行动。这个想法很简单明了,但是实现似乎并非如此。
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发送数据来永久清空队列。现在,我的问题是似乎没有可能将消息推送到队列中。当类型为“SEND”的消息到达时,应该发生这种情况,但是对于 worker 来说,它不能忙于处理任何事件。因此,它既可以循环访问队列,也可以推送消息,而不能两者都行。
我需要的是一种以某种方式将数据推送到此队列的方法。如果这不容易实现,那么我想知道是否有人能想到另一种方法来找出消息何时更快到达,然后将它们发送出去。有什么提示吗?
提前致谢!
最佳答案
您必须给工作人员一些时间来处理onmessage事件。进行while(true)
将占用所有处理时间,并且不允许执行任何事件。
例如,您可以将其更改为
function processMessageQueue() {
if(queue.length > 0) ws.send(queue.shift());
setTimeout(processMessageQueue, 50);
}
关于JavaScript:使用队列进行网络通信,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8775274/