Node.js сервер и HTTP/2 (2.0) с использованием Express.js
Здравствуйте! У меня возник вопрос: возможно ли в настоящее время создать HTTP/2 (HTTP 2.0) сервер с использованием node.js? Также интересует, существует ли версия express.js, поддерживающая HTTP/2? Спасибо за помощь!
2 ответ(ов)
Необходимость использования HTTP/2 с Express остается актуальной, и действительно существует открытый Pull Request для Express 5.0 с 2018 года (https://github.com/expressjs/express/pull/3730). На данный момент, пока этот PR не будет объединен, интеграция не будет работать из коробки.
Я создал решение в виде пакета, который называется http2-express-bridge, доступного по ссылке: https://www.npmjs.com/package/http2-express-bridge.
Вот пример использования:
const express = require('express')
const http2Express = require('http2-express-bridge')
const http2 = require('http2')
const { readFileSync } = require('fs')
// Используем обертку, которая возвращает приложение
const app = http2Express(express)
const options = {
key: readFileSync('<Certificate Key>'),
cert: readFileSync('<Certificate file>'),
allowHTTP1: true
};
app.get('/', function (req, res) {
res.send('Hello World')
})
const server = http2.createSecureServer(options, app)
server.listen(3000, () => {
console.log(`listening on port 3000`)
})
Это решение работает и автоматически переключается на HTTP/1.1, когда получает запрос по этому протоколу. Кроме того, я добавил метод 'res.push' для удобства реализации серверного пуша. Пакет совместим с ESModules и TypeScript, что делает его удобным для использования в современных приложениях.
Проблема, о которой идет речь, актуальна и по сей день (на момент написания этого ответа в 2016 году), поэтому я решил попробовать создать обходной путь, чтобы пакеты express и http2 работали вместе без проблем. Вот ссылка на пакет: express-http2-workaround.
Редактирование: Не работает на каких-либо версиях Node.js выше v8.4 из-за встроенного модуля 'http2'.
Установите через NPM:
npm install express-http2-workaround --save
Вот пример кода:
// Подключаем модули
var fs = require('fs');
var express = require('express');
var http = require('http');
var http2 = require('http2');
// Создаем приложение Express
var app = express();
// Настраиваем работу HTTP2 с Express (это должно быть до любого другого middleware)
require('express-http2-workaround')({ express: express, http2: http2, app: app });
// Настраиваем сервер HTTP/1.x
var httpServer = http.Server(app);
httpServer.listen(80, function(){
console.log("Express HTTP/1 сервер запущен");
});
// Настраиваем сервер HTTP/2
var httpsOptions = {
'key': fs.readFileSync(__dirname + '/keys/ssl.key'),
'cert': fs.readFileSync(__dirname + '/keys/ssl.crt'),
'ca': fs.readFileSync(__dirname + '/keys/ssl.crt')
};
var http2Server = http2.createServer(httpsOptions, app);
http2Server.listen(443, function(){
console.log("Express HTTP/2 сервер запущен");
});
// Обслуживаем контент
app.get('/', function(req, res){
res.send('Hello World! Via HTTP ' + req.httpVersion);
});
В приведенном выше коде находится рабочее приложение express, которое использует как модуль http Node.js (для HTTP/1.x), так и модуль http2 (для HTTP/2).
Как упоминается в README, этот подход создает новые объекты запроса и ответа express и устанавливает их прототипы на объекты IncomingMessage и ServerResponse от http2. По умолчанию это встроенные объекты IncomingMessage и ServerResponse от Node.js.
Надеюсь, это поможет! 😃
Ошибка: запрос слишком велик
Как получить параметры GET после "?" в Express?
Включение HTTPS в express.js
Express 4: Middleware для обработки ошибок не вызывается
Как вернуть результаты Mongoose из метода find?