在 JavaScript 中,有没有办法将 Web 套接字消息的处理推迟到设置标志之前?

Posted

技术标签:

【中文标题】在 JavaScript 中,有没有办法将 Web 套接字消息的处理推迟到设置标志之前?【英文标题】:In JavaScript is there a way to defer the processing of web socket messages until a flag is set? 【发布时间】:2015-07-30 13:04:11 【问题描述】:

背景:我有一个保存数据网格状态的服务器。网格不断更新 - 例如新行、更新行、删除行。我需要在网页上显示它并在更新时反映它们。

当网页最初加载时,我会进行 ajax 调用以检索该时间点的数据的初始快照。我正在使用 Web Sockets (Stomp) 来接收数据网格发生的任何更改的事件。

为了确保浏览器中显示的数据的正确性,我需要在获取数据的初始加载之前订阅事件消息,然后应用这些事件。这确保不会丢失任何事件,并且客户端状态与服务器状态同步。

因此,我需要一种机制,允许延迟处理传入事件,直到完成初始数据加载的处理。

请注意,通过 Stomp 发送的更新消息是关于所有客户端订阅的通用主题的。服务器端没有维护客户端会话状态。

编辑:我确实考虑过使用基于队列的方法。但是我认为这种方法仍然存在一些并发问题。基于@jfriend00 下面显示的示例代码:一旦完成初始数据处理并调用 processQueue() 函数,您仍然可能会收到事件。在这种情况下,您可能希望继续将这些附加到队列中。只有在队列为空时,您才希望将传入事件切换为由 processWsData() 函数直接处理。尽管我不完全确定如何解决此处存在的并发问题,即设置一个标志来表示初始数据处理已完成,并确保在设置该标志后项目不会被放入队列中。您基本上需要对标志进行一些同步。

【问题讨论】:

也许您可以在一切都设置好后向客户端发送一条 'state':'ready' 消息,并且在客户端站点上忽略在 'state':'ready' 之前收到的任何消息?跨度> 【参考方案1】:

这取决于你没有描述的一些事情是如何工作的。如果您首先设置 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 消息。

当然,有各种特定于数据的方法来确定您是否已经处理了给定的数据,但这些都取决于特定的数据。

【讨论】:

感谢您整理代码示例。请查看我对问题的编辑。

以上是关于在 JavaScript 中,有没有办法将 Web 套接字消息的处理推迟到设置标志之前?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Javascript 和 AJAX 将用户重定向到最近和最快的 Web 服务器?

如何调试在 iPad 上的 web 视图中运行的 Javascript?

有没有办法将JavaScript注入WebView供以后使用?

ios - 如何在 Web 视图中使用 javascript 打开 swift 视图?

有没有办法将 JavaScript 对象保存到 JSON 文件中,我可以选择保存它的目录吗?

有没有办法在 jQuery 或 javascript 中克隆表单字段值?