Background:我有一个服务器,用于保存数据网格的状态。网格是不断更新的——例如,新行、更新行、删除行。我需要在一个网页上显示这一点,并反映更新,因为他们发生。
当网页最初加载时,我调用ajax来检索那个时间点的数据的初始快照。我使用Web Sockets (Stomp)来接收发生在数据网格上的任何变化的事件。
为了确保浏览器中显示的数据的正确性,我需要在获得初始数据加载之前订阅事件消息,然后应用这些事件。这可以确保没有事件丢失,并且客户端状态与服务器状态同步。
因此,我需要一种机制,允许将传入事件的处理延迟到初始数据加载的处理完成。
请注意,通过Stomp发送的更新消息是关于所有客户机订阅的通用主题的。服务器端没有维护客户端会话状态。
编辑:我确实考虑过使用基于队列的方法。然而,我认为这种方法仍然存在一些并发性问题。根据下面@jfriend00显示的示例代码:一旦完成了初始数据处理并调用了processQueue()函数,您仍然可以获得传入的事件。在这种情况下,您将希望继续将这些附加到队列中。只有当队列为空时,您才希望将传入事件切换为由processWsData()函数直接处理。虽然我不完全确定如何解决这里存在的并发问题,即设置一个标志来表示初始数据处理已经完成,并确保在设置该标志后项目不会被放入队列中。实际上,您需要对标志进行一些同步。这取决于您没有描述的一些事情如何工作。如果您先设置websocket侦听器,然后进行初始数据抓取(就像您正在考虑的那样),那么您只需要推迟对传入消息的处理,直到初始数据完成处理。您可以为在进行初始数据抓取时到达的任何传入消息设置一个队列,然后在初始数据完成时处理排队的消息。
您没有展示任何代码(这总是使提供最佳答案变得更加困难),因此我将编写一些代码来向您展示这个概念:
var initalizeDone = false;
var initialQueue = [];
function processWsData(data) {
// implement code here to process a webSocket message
}
function processQueue() {
for (var i = 0; i < initialQueue.length; i++) {
processWsData(initialQueue[i]);
}
}
// websocket data handler
ws.onmessage = function(event) {
if (initializeDone) {
initialQueue.push(event.data);
} else {
processWsData(event.data);
}
}
然后在任何代码中进行初始处理,当它完成处理该数据时,它会这样做,以便赶上在处理时排队的任何数据:
processQueue();
initalizeDone = true;
如果你的代码不能处理重复事件的可能性,在数据的初始抓取和webSocket中,那么你将不得不以任何最适合你的数据的方式来修复它。一种使解决此类问题变得更简单的技术是为从服务器发送的每个数据块分配一个单调递增的数字。然后,您可以记录在初始数据抓取中获得的任何数据块的最高id,并跳过不高于此值的任何websocket消息。
当然,有各种特定于数据的方法来确定您是否已经处理了给定的数据,但这些都取决于特定的数据。