Могу ли я контролировать поток на своих веб-сайтах?

Я использую websockets для передачи видео-y изображений с сервера, написанного на Go, клиенту, который является HTML-страницей. Ниже приведен мой опыт работы с Chrome.

Я получаю изображения через обработчик onmessage websocket. При получении изображения мне может потребоваться выполнить несколько задач асинхронно, прежде чем я смогу отобразить изображение. Даже если эти задачи еще не закончены, может произойти еще одно onmessage(). Я не хочу ставить в очередь изображения, так как на данный момент я не могу действовать так же быстро, как это происходит на сервере, и потому, что нет смысла отображать старые изображения. Я также не хочу бросать эти изображения, я не хочу их вообще получать.

Будет ли клиент использовать традиционное TCP-соединение, он просто прекратит чтение из соединения. Это приведет к заполнению буфера приема, закрытию окна приема и, в конечном итоге, приостановке отправки изображений на сервере. Как только клиент начнет чтение, буферы приема будут пусты, откроется окно приема, и сервер возобновит передачу. Каждый раз, когда мой сервер начинает отправлять изображение, он выбирает самый свежий. Это самое лучшее поведение, а также контроль потока TCP гарантируют разумное поведение во многих случаях.

Возможно ли иметь функции управления потоком TCP, на которых основаны веб-сайты, с веб-окнами? Меня особенно интересует решение, которое зависит от управления потоком TCP и управления потоком на уровне приложений, поскольку это приводит к нежелательной дополнительной задержке.

Ответ 1

Я сомневаюсь, что вы просите, возможно. Интерфейс для этой функциональности отсутствует в Спецификация API WebSocket. Однако спецификацией является требование, чтобы управление базовым сокетом осуществлялось в фоновом режиме за пределами script, использующего WebSocket, так что script не блокируется действиями WebSocket. Когда сокет принимает входящие данные, он обертывает данные внутри сообщения и ставит его в очередь для обработки WebSocket script. Нет ничего, чтобы заблокировать сокет от чтения большего количества данных, пока сообщения остаются в очереди, ожидая, когда script обработает их.

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

Ответ 2

Вы можете выполнять управление потоком в соединениях WebSocket (на основе адаптации прокси-сервера TCP). Вот две ссылки, которые помогут вам начать:

Раскрытие информации: Я являюсь оригинальным автором Autobahn и работаю в Tavendo.

Ответ 3

Теперь возможно иметь потоки в WebSocket. Chrome 78 будет поставляться с новым API-интерфейсом WebSocketStream, который поддерживает противодавление.

Вот цитата из статуса платформы Chrome:

API WebSocket предоставляет интерфейс JavaScript для RFC6455 Протокол WebSocket. В то время как это служило хорошо, это неловко с эргономическая перспектива и отсутствует важная особенность обратное давление. Цель API WebSocketStream - решить эти недостатки путем интеграции потоков с API WebSocket.

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

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

К сожалению, это API-интерфейс только для Chrome, и нет веб-стандарта на момент написания.

Для получения дополнительной информации см.: