HTTP / 2 начинает использоваться все больше и больше (он подскочил с 11% в начале этого года до 18% общего использования в Интернете). Если вы помните наши последние сообщения в блоге о HTTP / 2, такие как HTTP / 2: взгляд в будущее Интернета, Альтернативы HTTP / 2 или Оптимизация с помощью Server Push и Service Workers, вы можете вспомнить некоторые подробностей в протоколе HTTP / 2 и отличиях от первой версии. Ознакомьтесь с ними, если нет, так как мы не будем вдаваться в детали RFC в этом блоге.
В наших последних сообщениях в блоге мы упоминали, что версия HTTP / 2 начала реализовываться в репозитории nodejs / http2, но в то время не было решено, будет ли она объединена с основными модулями Node.js. или если это будет внешний модуль. Основная причина появления новой реализации заключалась в том, что другие реализации не полностью соблюдают HTTP / 2 RFC.
В конце концов, был отправлен запрос на включение, чтобы добавить его в ядро. Он был объединен и включен как экспериментальный под флагом (--expose-http2
) в августе (версия 8.4.0).
После объявления в Twitter о том, что флаг собирается быть удаленным в выпуске 8.x LTS, Node.js в конечном итоге избавился от флага в версии 8.8.0 (24 октября). HTTP / 2 по-прежнему считается экспериментальным и, несмотря на то, что он еще не готов на 100%, вы уже можете начать экспериментировать с ним и ознакомиться с документацией по HTTP / 2 API.
Играя вокруг
Создание сервера HTTP / 2 не должно быть таким сложным. Фактически, если у вас уже есть опыт работы с Node.js, он должен быть очень похож на то, к чему вы привыкли. Посмотрите следующий пример:
const http2 = require('http2'), fs = require('fs');
const options = { key: fs.readFileSync('keys/server.key'), cert: fs.readFileSync('keys/server.crt') };
const server = http2.createSecureServer(options); server.on('stream', (stream, requestHeaders) => { stream.respond({ 'content-type': 'text/html', ':status': 200 }); stream.end('<h1>Hi, and welcome to YLD blog!</h1>'); }); server.listen(3000);
Основные отличия заключаются в том, что мы требуем http2 и отправляем параметры учетных данных функции http2.createSecureServer
. Браузеры реализуют HTTP / 2 только по протоколу HTTPS, убедитесь, что вы настраиваете соединение TLS.
Вы, наверное, заметили, что мы везде используем стримы. Однако есть API совместимости, который позволяет легко переходить с HTTP / 1 на HTTP / 2. Вот как вы можете настроить обработчики запросов и ответов, как вы привыкли:
// ...
const onRequestHandler = (req, res) => { const { socket: { alpnProtocol } } = req.httpVersion === '2.0' ? req.stream.session : req; res.writeHead(200, `Hi, and welcome to YLD blog! The server you are talking with supports ${alpnProtocol} `); }
const server = http2.createSecureServer( options, onRequestHandler ).listen(3000);
Обработчики запросов и ответов будут работать должным образом, несмотря на то, что у них уже есть дополнительная информация HTTP / 2, например, если соединение использует ALPN (используется только в HTTP / 2).
Одной из самых интересных функций HTTP / 2 является отправка файлов на сервер, и отправлять файлы довольно просто. В следующем примере мы видим, что каждый раз, когда запрашивается индексный маршрут, отправляется файл CSS:
const onRequestHandler = (req, res) => { const currentUrl = url.parse(req.url);
if (currentUrl.pathname === '/') { const cssFile = { path: '/style.css', filePath: './style.css', headers: { 'content-type': 'text/css' } }; pushAsset(res.stream, cssFile);
// ...
и вы можете реализовать pushAsset
следующим образом:
const pushAsset = (stream, file) => {
const filePath = path.join(__dirname, file.filePath);
stream.pushStream({ [HTTP2_HEADER_PATH]: file.path }, (pushStream) => {
pushStream.respondWithFile(filePath, file.headers);
});
}
Фактически, API Node.js позволяет вам отправить файл с помощью responseWithFile или дескриптора файла с responseWithFD. file.path
здесь весьма уместен, потому что это будет путь, который будет запрошен. например если файл запрашивается окном в /styles/style.css
, путь нужно будет соответствующим образом изменить. В нашем случае это просто /style.css
. Обратите внимание, что мы можем отправить столько файлов, сколько захотим, и вы можете отправить то, что, по вашему мнению, имеет отношение к странице индекса. Посмотрите полный пример.
Вы также можете протестировать с помощью Server Push и Service Workers, как мы делали в Оптимизация с помощью Server Push и Service Workers. Ознакомьтесь с примером использования базовой реализации HTTP / 2 Node.js.
Рамки и ожидания, следите за обновлениями!
Плохая новость в том, что такие фреймворки, как Express или Hapi.js еще не поддерживают HTTP / 2. Хорошей новостью является то, что это скоро будет реализовано, и оно должно быть очень похоже на реализацию, используемую для spdy или других старых модулей HTTP / 2 для Node.js.
Если вы хотите быть в курсе последних новостей, ознакомьтесь со следующими темами:
Выражать:
- Https://github.com/expressjs/express/issues/3388
- Https://github.com/expressjs/express/pull/3390
- Https://github.com/nodejs/node/issues/15203
Hapi.js:
Хотите узнать больше?
Я выступал на эту тему на EmpireConf 13 октября. Если вам это интересно и если вы хотите узнать больше о HTTP / 2, посмотрите мой доклад Рост HTTP / 2, где я объясняю HTTP / 2 с помощью метафоры оркестра! Вы также можете найти примеры кода в репозитории github.com/sericaia/http2-examples-empireconf.
Опубликовано Даниэлой Матос де Карвалью - разработчиком программного обеспечения в YLD.