Блокирует ли метод JavaScript WebSocket.send?

Если я отправляю большой Blob или же ArrayBuffer над JavaScript WebSocket через его send метод... делает send блок вызова метода, пока данные не отправлены, или он создает копию данных для асинхронной отправки, чтобы вызов мог вернуться немедленно?

От того, насколько я понимаю, связан ли (без ответа) вопрос, вызовет ли быстрая серия посылок задержку событий onmessage, как, по-видимому, кто-то описал в Mobile Safari: явное поведение блокировки в веб-сокете JavaScript в мобильном Safari

1 ответ

На основании описания bufferedAmount атрибут, я сделал вывод, что send должен вернуться немедленно, потому что в противном случае bufferedAmount всегда будет ноль. Если он не равен нулю, тогда должны быть данные, буферизованные от предыдущего вызова для отправки, и если отправка буферизует данные, нет причин для их блокировки.

С http://dev.w3.org/html5/websockets/

Атрибут bufferedAmount должен возвращать количество байтов данных приложения (текстовые и двоичные данные UTF-8), которые были поставлены в очередь с помощью send(), но которые на момент последнего запуска цикла обработки событий не выполнялись, еще не были переданы в сеть. (Таким образом, это включает любой текст, отправленный во время выполнения текущей задачи, независимо от того, может ли пользовательский агент передавать текст асинхронно с выполнением сценария.) Это не включает накладные расходы на кадрирование, вызванные протоколом, или буферизацию, выполняемую операционной системой. или сетевое оборудование. Если соединение закрыто, значение этого атрибута будет увеличиваться только при каждом вызове метода send() (число не сбрасывается в ноль после закрытия соединения).

В этом простом примере атрибут bufferedAmount используется для гарантии того, что обновления отправляются либо со скоростью одного обновления каждые 50 мс, если сеть может обрабатывать эту скорость, или с любой скоростью, с которой может обрабатывать сеть, если это слишком быстро.

var socket = new WebSocket('ws://game.example.com:12010/updates');
socket.onopen = function () {
    setInterval(function() {
       if (socket.bufferedAmount == 0)
           socket.send(getUpdateData());
    }, 50);
};

Атрибут bufferedAmount также можно использовать для насыщения сети без отправки данных с более высокой скоростью, чем может обрабатывать сеть, хотя это требует более тщательного контроля значения атрибута с течением времени.

Другие вопросы по тегам