Комментарии 26
Отличная статья, которая задаёт правильный вектор для начинающих.
А правда, что WebSocket - это устаревшая технология и применяется только с HTTP1?
Впервые о таком слышу, что это устаревшая технология. Слушай, WebSocket сейчас как стандарт для real-time приложений поставляется. По поводу версий HTTP - WebSocket имеет нативную поддержку в 1.0 и 1.1 версиях. Т.е это просто протокол для двусторонней связи, в других версиях HTTP - у него есть замена в виде протокола WebTransport
Спасибо за проявленный интерес)
Ну, просто я делал приложение на базе node'овских http / http2 / https серверов и в качестве прокси-сервера использовал apache. Само приложение могло использовать любой из трёх серверов, в зависимости от настроек. Так вот, веб-сокеты из браузера, через апач и в моё приложение работали только для режима HTTP1 (browser -> HTTPS -> apache -> HTTP1 -> app).
SSE, кстати, работало и для первой, и для второй версии HTTP без проблем.
Спасибо за ссылку. Хорошо уже, что хотя бы намерения есть. Просто обычный POST фронта на бэк и SSE с бэка на фронт дают аналогичную веб-сокетам функциональность, но при этом работают через все версии протокола. Вот я и спросил :)
Правда ещё пару-тройку лет назад nginx не проксировал HTTP/2. Надеюсь, что на сейчас ситуация исправилась, не проверял. Так что вполне себе возможно, что разрабы веб-серверов просто не успевают за разрабами протоколов.
Post с фронта не аналогично ws как минимум потому что трата ресурсов на установку соединения как на клиенте так и на сервере хотя в хттп2 это слегка иначе но есть подводные камни.
Ws это единственное апи для реалтайм задач в веб
... которое до сих пор не проксируется по HTTP2 в самых популярных веб-серверах (apache2 & nginx). Вот и непонятка выходит, раз оно такое безальтернативно популярное, то почему так?
Так это ведь разные протоколы. Вебсокет использует HTTP только для установки соединения. Дальше обмен данными происходит по этому соединению. Какой смысл использовать для этого именно HTTP2?
У меня nodejs-приложение, которое стоит за прокси-сервером (apache или nginx) и обрабатывает HTTP-запросы. Часть запросов - статика, часть - API (JSON POST), часть - SSE. И всё это это прекрасно крутится на http2, который замечательно проксируется через apache, до тех пор, пока я не решу использовать веб-сокеты. Как только я решаю использовать веб-сокеты, весь мой зоопарк вынужденно съезжает на HTTP/1, потому что веб-сокеты с HTTP/2 "не дружат" (или HTTP/2 с веб-сокетами).
Резюме по проблеме от ИИ:
WebSockets не работают напрямую через HTTP/2.
Можно использовать CONNECT для создания туннеля (прим. - на вебсокет-сервер, можно в том же nodejs-приложении, но на другом порту).
Для одностороннего потока можно использовать SSE.
Для двустороннего общения WebTransport (HTTP/2, HTTP/3) — перспективное, но пока не везде доступное решение.
Вот и получается, что я не могу иметь одно nodejs-приложение, которое бы обрабатывало статику / API / SSE / WebSockets на одном порту по HTTP/2. По HTTP/1 всё работает прекрасно, а по HTTP/2 - мешают WebSockets.
HTTP/2 просто не поддерживает 101 статус (смену протокола).
И всё это это прекрасно крутится на http2, который замечательно проксируется через apache, до тех пор, пока я не решу использовать веб-сокеты.
А как вы их пытаетесь использовать? Вам же для этого в любом случае нужен отдельный веб-сервер, на него и следует тогда эти запросы проксировать (можно по сокетам, а наружу один порт). Либо какой-то универсальный веб-сервер, не знаю как это на nodejs делается.
Как-то так:
/** @type {Server|Http2Server|Http2SecureServer} */
const server = useHttp1 ? initHttp1()
: (key && cert) ? initHttps(key, cert) : initHttp2();
/** @type {WebSocketServer} */
const socketServer = new WebSocketServer({noServer: true});
const onUpgrade = createListener(socketServer);
server.on('upgrade', onUpgrade);
В зависимости от конфига выбираешь, какой из встроенных nodejs-серверов будет обрабатывать HTTP-запросы (их в node три: http, http2, https). Потом создаёшь, опять же, в зависимости от конфига, WebSocketServer и говоришь, что он работает в рамках уже существующего веб-сервера (перенаправляешь на него события onUpgrade
). Таким образом, есть один веб-сервер который слушает один порт и может работать либо standalone (в деве), либо за проксирующим/балансирующим веб-сервером (на проде). Все три node-сервера по интерфейсам сопоставимы, а дальнейшему коду всё равно, как пришёл запрос (HTTP/1/2/S), вебсокеты немного в стороне, но тоже через тот же порт работают. Когда HTTP/1 - всё крутится.
Не вижу проблем при использовании http2 запускать его на нужном порту и параллельно запускать http для ws на сокете. Разве что на винде может не сработать. Хотя, судя по доке, IPC там поддерживается, так что и на винде должно работать.
О nginx и http2 https://nginx.org/en/docs/http/ngx_http_v2_module.html.
Что касается использования post и sse вместо ws, то полностью солидарен с Вами. Не так много категорий приложений, где именно необходим жесткий реалтайм.
Зачем эта статья?
И ни намёка на ответ. Почему? Потому что статья — сгенерированный нейросетью огрызок, который не раскрывает тему, а автор даже не прочитал текст перед публикацией.
Кстати, может быть кто-нибудь реализовывал чаты? Есть ли ощутимая разница при использовании SSE и WebSocket, если обмен данными осуществляется в текстовом формате?
Особенно интересует нагрузка и на клиент, и на бэк при использовании этих способов. Выше справедливо отметили http/2, который может снизить сетевую нагрузку для клиента. Кто-то копал в эту сторону?
На уровне пары человек в чате - разница вряд ли будет. Я не заметил, по крайней мере. Уверен, что она есть, но для человека незаметна. Делал как-то такую поделку (чат на SSE) - вполне себе всё бодро бегало.
Что же касается высоконагруженных приложений, то там у меня никакого опыта.
Введение в WebSocket и Socket.IO