处理websocket发送在握手期间没有消息丢失



我想实现以下行为。假设客户端有一个按钮,它触发一个通过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);
    }
}

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

我想避免这种情况,我将感谢任何想法,评论或建议。

我想你担心handshakcomplete会在test (== CONNECTING)和bind()发生之间触发,并且永远不会发送handshakcomplete的消息。

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

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

相关内容

  • 没有找到相关文章