Щойно закінчив читати специфікацію HTTP / 2 , я думаю, що HTTP / 2 робить застарілі веб-розетки для більшості випадків використання, але, можливо, не для всіх.
PUSH_PROMISE
(розмовно відомий як серверний поштовх) тут не проблема. Це просто оптимізація продуктивності.
Основний випадок використання веб-сокетів у браузері - це включення двостороннього потокового передавання даних. Отже, я думаю, що питанням ОП стає те, чи HTTP / 2 робить кращу роботу з включення двостороннього потоку в браузері, і я думаю, що так, це так.
Перш за все, це є бі-ді. Просто прочитайте вступ до розділу потоків :
"Потік" - це незалежна двонаправлена послідовність кадрів, що обмінюються між клієнтом і сервером у межах HTTP / 2 з'єднання. Потоки мають кілька важливих характеристик:
Одне з'єднання HTTP / 2 може містити декілька паралельно відкритих потоків з перемежуванням кадрів кінцевої точки з декількох потоків.
Потоки можуть встановлюватися та використовуватися в односторонньому порядку або спільно використовуватися клієнтом або сервером.
Потоки можуть бути закриті будь-якою кінцевою точкою.
Статті як це (пов'язані в іншу відповідь) не праві про цей аспект HTTP / 2. Кажуть, це не біді. Подивіться, є одне, що не може статися з HTTP / 2: Після того, як з'єднання буде відкрито, сервер не може ініціювати звичайний потік, а лише push-stream. Але як тільки клієнт відкриває потік, надсилаючи запит, обидві сторони можуть в будь-який час надсилати кадри DATA через стійкий сокет - повний bidi.
Це не сильно відрізняється від websockets: клієнт повинен ініціювати запит на оновлення websocket і до того, як сервер також може надсилати дані через.
Найбільша відмінність полягає в тому, що, на відміну від websockets, HTTP / 2 визначає власну семантику мультиплексування: як потоки отримують ідентифікатори та як кадри несуть ідентифікатор потоку, на якому вони перебувають. HTTP / 2 також визначає семантику управління потоком для пріоритетності потоків. Це важливо для більшості реальних програм bidi.
(Ця неправильна стаття також говорить про те, що стандарт Websocket має мультиплексування. Ні, це не так. Це не дуже важко знайти це, просто відкрийте Websocket RFC 6455 і натисніть ⌘-F і введіть "мультиплекс". Після того, як прочитаєте
Протокол призначений для розширення; майбутні версії, ймовірно, введуть додаткові поняття, такі як мультиплексування.
Ви побачите, що існує розширення для проекту мультиплексування Websocket 2013 року . Але я не знаю, які браузери, якщо такі є, підтримують це. Я б не намагався будувати свій SPA webapp на задній частині цього розширення, особливо при надходженні HTTP / 2, підтримка ніколи не надійде).
Мультиплексування - це саме та річ, яку вам зазвичай доводиться робити кожен раз, коли ви відкриваєте веб-розетку для bidi, скажімо, для живлення реально оновлюваного додатка для однієї сторінки. Я радий, що це у специфікації HTTP / 2, про яку потрібно подбати раз і назавжди.
Якщо ви хочете знати, що HTTP / 2 може зробити, просто подивіться на gRPC. gRPC реалізований через HTTP / 2. Подивіться конкретно на параметри напів- та повного дуплексного потоку, які пропонує gRPC. (Зверніть увагу, що gRPC зараз не працює в браузерах, але це насправді тому, що браузери (1) не піддають кадр HTTP / 2 клієнтському javascript, і (2) взагалі не підтримують трейлери, які використовуються в специфікація gRPC)
Де веб-розетки все-таки мають місце? Найбільше - це бінарні дані, що надсилаються на сервер. HTTP / 2 дозволяє бінарні дані, що відштовхуються сервером, і> браузер, але вони не піддаються дії в JS браузера. Для таких програм, як штовхання кадрів аудіо та відео, це привід використовувати веб-розетки.
Редагувати: 17 січня 2020 року
З часом ця відповідь поступово піднімалася до вершини (що добре, оскільки ця відповідь більш-менш правильна). Однак все ще є випадкові коментарі, які говорять про те, що це неправильно з різних причин, як правило, пов’язаних з деякою плутаниною щодо PUSH_PROMISE
того, як насправді споживати сервер, орієнтований на повідомлення -> клієнтське натискання в одному додатку сторінки. Крім того, у веб-переглядачі є випадок використання веб-сокетів, який є бінарними даними, висунутими сервером. Для текстових даних, включаючи JSON, не використовуйте веб-розетки, використовуйте SSE.
Для резюме: протокол HTTP / 2 є повним бі-ді. Однак сучасні веб-браузери не піддають рамковому протоколу HTTP / 2 протокол JavaScript . Незважаючи на те, що якщо ви робите кілька запитів одного і того ж походження через з'єднання HTTP / 2, під кришкою весь цей трафік стає мультиплексованим на одному з'єднанні (і це те, що нас хвилює!).
Отже, якщо вам потрібно створити додаток для чату в реальному часі, скажімо, де вам потрібно транслювати нові чатові повідомлення всім клієнтам у чаті, які мають відкрите з'єднання, ви можете (і, мабуть, повинні) це зробити без веб-розеток.
Ви б використовували події, надіслані сервером, щоб підштовхувати повідомлення вниз, а " Вибрати api" для надсилання запитів. Події, надіслані сервером (SSE) - маловідомий, але добре підтримуваний API, який відкриває потік сервер-клієнт, орієнтований на повідомлення. Хоча він не схожий на клієнтський JavaScript, під кришкою браузера ваш браузер (якщо він підтримує HTTP / 2) повторно використовувати одне TCP-з'єднання для мультиплексування всіх цих повідомлень. Немає втрати ефективності, і насправді це виграш над веб-розетками. Вам потрібно кілька потоків? Відкрийте кілька джерел подій! Вони будуть автоматично мультиплексовані для вас.
Окрім того, що ефективніше використання ресурсів та менша початкова затримка, ніж рукостискання веб-розетки, події, надіслані сервером, мають і приємне властивість: вони автоматично відступають і працюють над HTTP / 1.1. Але коли у вас є з'єднання HTTP / 2, вони працюють надзвичайно добре.
Ось хороша стаття з прикладом у реальному світі щодо реалізованого SPA.