Обрабатывать отправку websocket во время рукопожатия без потери сообщения - PullRequest
1 голос
/ 23 июля 2011

Я бы хотел добиться следующего поведения.Предположим, что на стороне клиента есть кнопка, которая запускает функцию, которая отправляет сообщение через веб-сокет.При первом вызове этой функции создается экземпляр WebSocket, который затем используется в будущих вызовах.

Создание экземпляра WebSocket не является блокирующим.Конструктор немедленно возвращает объект WebSocket, начиная рукопожатие в фоновом режиме.Успешное соединение запускает обратный вызов onopen.

Проблема появляется, когда поступает второй вызов, и веб-сокет все еще выполняет рукопожатие (например, пользователь делает двойной щелчок по кнопке).Все сообщения должны быть поставлены в очередь и отправлены после завершения рукопожатия.

В следующем фрагменте кода используется 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);
    }
}

Возможно, что условие в звездной строке будет оценено как истинное, и в этот момент веб-сокет перейдет в состояние ОТКРЫТО, обратный вызов onopen будет выполнен, и только после этого текущее сообщение будет добавлено в очередь в ожидании события handshakeComplete.Это может привести к потере сообщений.

Я бы хотел этого избежать, и я был бы признателен за любые идеи, комментарии или предложения.

1 Ответ

0 голосов
/ 01 мая 2012

Я думаю, вы обеспокоены тем, что рукопожатие может завершиться между тестом (== СОЕДИНЕНИЕ) и когда происходит связывание (), и сообщение для рукопожатия не будет отправлено.

Теоретически, если всесуществовал JS, это было бы неправильно, так как событие не сработало бы до завершения текущего кода.Однако в действительности событие может быть сгенерировано в другом потоке в фоновом режиме и просто должно быть run на переднем плане после того, как мы достигнем стабильного состояния.

Ответ заключается в том, чтобы не вставлять сообщениев обработчике рукопожатия.Я предлагаю добавить сообщение в очередь / массив, а в обработчике onopen обработать массив.Событие onopen может запускаться (ставиться в очередь) во время выполнения, но оно не будет запускать , пока мы не достигнем стабильного состояния (когда все сообщения находятся в очереди / массиве).

...