Могу ли я контролировать поток на своих веб-сайтах?
Я использую 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, и нет веб-стандарта
на момент написания.
Для получения дополнительной информации см.: