【问题标题】:Handle websocket send during handshake without message loss在握手期间处理 websocket 发送而不会丢失消息
【发布时间】:2011-10-11 10:15:18
【问题描述】:

我想实现以下行为。假设客户端有一个按钮,它触发了一个通过 websocket 发送消息的函数。第一次调用此函数时,会创建一个 WebSocket 实例,然后在以后的调用中使用。

创建 WebSocket 实例是非阻塞的。构造函数立即返回一个 WebSocket 对象,在后台开始握手。连接成功触发 onopen 回调。

当第二个呼叫进来并且 websocket 仍在执行握手时出现问题(例如,用户双击按钮)。 websocket完成握手后,所有消息都需要排队发送。

以下代码使用 jQuery 和自定义事件来收集握手期间收到的所有消息。

var ws = null;

function sendMessage(message) {
    if (!ws) {
        ws = new WebSocket("ws://example.com");
        ws.onopen = function() {
            $(document).trigger('handshakeComplete');
        }
    }
    if (ws.readyState == WebSocket.CONNECTING) { // *
            $(document).bind('handshakeComplete', message, function(event) {
                ws.send(event.data);
            });
    } else if (ws.readyState == WebSocket.OPEN) {
        // use the persistent connection
        ws.send(message);
    }
}

有可能在星号行的条件被评估为真,在那一刻,websocket 进入 OPEN 状态,onopen 回调被执行,只有在此之后,当前消息才被添加到队列中等待握手完成事件。这会导致消息丢失。

我想避免这种情况,如果有任何想法、cmets 或建议,我将不胜感激。

【问题讨论】:

  • 您是要阻止发送相同的消息(通过单击两次相同的按钮)仅在协商连接时发送,还是在任何时候发送?
  • 我并不想阻止发送任何消息。假设消息是单击按钮时的时间戳。使用上面的代码 sn-p,我不能保证所有消息都被发送。
  • 我不太明白你的问题。什么时候丢弃消息?请您在您的代码清单下改写一下您的段落吗?
  • @fmoga,你找到解决办法了吗?

标签: javascript websocket send handshake


【解决方案1】:

我认为您担心握手完成可能会在测试 (== CONNECTING) 和 bind() 发生之间触发,并且永远不会发送握手完成的消息。

理论上,如果所有存在的都是 JS,那将是错误的,因为在当前代码完成之前事件不会触发。然而,实际上事件可能在后台的另一个线程上生成,并且在我们达到稳定状态后才在前台运行

答案是不要将消息嵌入到握手事件处理程序中。我建议将消息​​添加到队列/数组中,并在 onopen 处理程序中处理数组。 onopen 事件可以在我们执行时触发(排队),但在我们达到稳定状态(所有消息都在队列/数组中)之前它不会运行

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-05
    • 1970-01-01
    • 1970-01-01
    • 2020-04-09
    • 2017-05-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多