在握手期间处理websocket发送而不会丢失消息

时间:2011-07-22 22:35:33

标签: javascript websocket send handshake

我想实现以下行为。假设客户端有一个按钮,它触发一个通过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事件。这会导致消息丢失。

我想避免这种情况,我将不胜感激任何想法,意见或建议。

1 个答案:

答案 0 :(得分:0)

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

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

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