Как немедленно закрыть сервер HTTP (Node.js)?

У меня есть приложение Node.js, которое содержит HTTP-сервер.

В конкретном случае мне нужно программно завершить работу этого сервера. То, что я сейчас делаю, вызывает функцию close() , но это не помогает, так как он ожидает, что все сохраненные живые соединения закончатся первым.

Таким образом, в основном это завершает работу сервера, но только после минимального времени ожидания 120 секунд. Но я хочу, чтобы сервер немедленно отключился – даже если это означает разрыв с обработанными в настоящее время запросами.

То, что я не могу сделать, – это просто

 process.exit(); 

поскольку сервер является только частью приложения, а остальная часть приложения должна работать. То, что я ищу, концептуально такое, как server.destroy(); или что-то типа того.

Как я мог это достичь?

PS: Обычно требуется время ожидания для соединений, поэтому на этот раз это не жизнеспособный вариант.

8 Solutions collect form web for “Как немедленно закрыть сервер HTTP (Node.js)?”

Фокус в том, что вам нужно подписаться на событие connection сервера, которое дает вам сокет нового соединения. Вам нужно запомнить этот сокет, а позже, сразу после socket.destroy() server.close() , уничтожить этот сокет, используя socket.destroy() .

Кроме того, вам нужно прослушать событие close сокета, чтобы удалить его из массива, если он естественным образом исчезнет, ​​потому что его тайм-аут продолжительности работы заканчивается.

Я написал небольшое примерное приложение, которое вы можете использовать, чтобы продемонстрировать это поведение:

 // Create a new server on port 4000 var http = require('http'); var server = http.createServer(function (req, res) { res.end('Hello world!'); }).listen(4000); // Maintain a hash of all connected sockets var sockets = {}, nextSocketId = 0; server.on('connection', function (socket) { // Add a newly connected socket var socketId = nextSocketId++; sockets[socketId] = socket; console.log('socket', socketId, 'opened'); // Remove the socket when it closes socket.on('close', function () { console.log('socket', socketId, 'closed'); delete sockets[socketId]; }); // Extend socket lifetime for demo purposes socket.setTimeout(4000); }); // Count down from 10 seconds (function countDown (counter) { console.log(counter); if (counter > 0) return setTimeout(countDown, 1000, counter - 1); // Close the server server.close(function () { console.log('Server closed!'); }); // Destroy all open sockets for (var socketId in sockets) { console.log('socket', socketId, 'destroyed'); sockets[socketId].destroy(); } })(10); 

В основном, он запускает новый HTTP-сервер, рассчитывает от 10 до 0 и закрывает сервер через 10 секунд. Если соединение не установлено, сервер немедленно отключается.

Если соединение установлено и оно все еще открыто, оно уничтожается. Если он уже умер естественным образом, в этот момент распечатывается только сообщение.

Я нашел способ сделать это без необходимости отслеживать подключения или закрывать их. Я не уверен, насколько это надежна в версиях Node или есть какие-то негативные последствия для этого, но, похоже, он отлично работает для того, что я делаю. Хитрость заключается в том, чтобы испустить событие «закрыть», используя setImmediate прямо после вызова метода close . Это работает так:

 server.close(callback); setImmediate(function(){server.emit('close')}); 

По крайней мере, для меня это освобождает порт, чтобы я мог запустить новую службу HTTP (S) к моменту вызова callback (что почти мгновенно). Существующие соединения остаются открытыми. Я использую это для автоматического перезапуска службы HTTPS после обновления сертификата Let’s Encrypt.

Если вам нужно сохранить процесс в живых после закрытия сервера, то решение Golo Roden, вероятно, является лучшим.

Но если вы закрываете сервер как часть изящного завершения процесса, вам просто нужно:

 var server = require('http').createServer(myFancyServerLogic); server.on('connection', function (socket) {socket.unref();}); server.listen(80); function myFancyServerLogic(req, res) { req.connection.ref(); res.end('Hello World!', function () { req.connection.unref(); }); } 

В принципе, сокеты, используемые вашим сервером, будут поддерживать этот процесс только в том случае, если они действительно выполняют запрос. Хотя они просто сидят там без дела (из-за подключения Keep-Alive), вызов server.close() закроет процесс, пока нет ничего, что обеспечило бы сохранение этого процесса. Если вам нужно делать другие вещи после закрытия сервера, как часть вашего изящного выключения, вы можете подключиться к process.on('beforeExit', callback) чтобы закончить ваши изящные процедуры выключения.

Библиотека https://github.com/isaacs/server-destroy обеспечивает простой способ destroy() сервер с поведением, желательным в вопросе (путем отслеживания открытых соединений и уничтожения каждого из них на сервере destroy, как описано в других ответы).

Как говорили другие, решение состоит в том, чтобы отслеживать все открытые сокеты и закрывать их вручную. Мощный мой пакет узлов может сделать это за вас. Пример (с помощью выражения, но вы можете использовать killable для любого экземпляра http.server ):

 var killable = require('killable'); var app = require('express')(); var server; app.route('/', function (req, res, next) { res.send('Server is going down NOW!'); server.kill(function () { //the server is down when this is called. That won't take long. }); }); var server = app.listen(8080); killable(server); 

Лучше всего было бы убить соединения вручную (т. Е. Принудительно закрыть его сокеты).

В идеале, это должно быть сделано, врываясь в внутренние части сервера и закрывая его розетки вручную. Кроме того, можно запустить команду оболочки, которая делает то же самое (при условии, что у сервера есть соответствующие привилегии и c.)

Еще один пакет nodejs для выполнения отключений, связанных с отключением: http-shutdown , который, по-видимому, поддерживается на момент написания статьи (сентябрь 2016 г.) и работал для меня на NodeJS 6.x

Из документации

Применение

В настоящее время существует два способа использования этой библиотеки. Первая – это явная упаковка объекта Server:

 // Create the http server var server = require('http').createServer(function(req, res) { res.end('Good job!'); }); // Wrap the server object with additional functionality. // This should be done immediately after server construction, or before you start listening. // Additional functionailiy needs to be added for http server events to properly shutdown. server = require('http-shutdown')(server); // Listen on a port and start taking requests. server.listen(3000); // Sometime later... shutdown the server. server.shutdown(function() { console.log('Everything is cleanly shutdown.'); }); 

Второй неявно добавляет функциональность прототипа к объекту Server:

 // .extend adds a .withShutdown prototype method to the Server object require('http-shutdown').extend(); var server = require('http').createServer(function(req, res) { res.end('God job!'); }).withShutdown(); // < -- Easy to chain. Returns the Server object // Sometime later, shutdown the server. server.shutdown(function() { console.log('Everything is cleanly shutdown.'); }); 

process.exit (код); // код 0 для успеха и 1 для отказа

  • HttpClient 4.0.1 - как освободить соединение?
  • Мгновенно обнаруживать отключение клиента от серверного сокета
  • Запустить командный файл с командой psql без пароля
  • mySQL - создание новой таблицы с использованием данных и столбцов из трех таблиц
  • java.rmi.ConnectException: подключение отказалось от хоста: 127.0.1.1;
  • Соединение RMI отказалось на localhost
  • Возвращаемое значение для функции внутри блока
  • проверить подключение к Интернету в cocoa-приложении
  • Interesting Posts

    «Параметр» против «Аргумент»

    Какая правильная альтернатива статическому наследованию метода?

    Получите pdf-вложения из Gmail в виде текста

    Linux: приглашение раскраски bash нарушит возврат каретки

    string.split – с помощью множественного символьного разделителя

    Можете ли вы указать git-shell в .ssh / authorized_keys для ограничения доступа только к git-командам через ssh?

    Как отключить (подписи) проверку в реальном времени и мониторинг поведения в поведении в Windows Defender?

    PhoneGap для iPhone: проблема загрузки внешнего URL

    MVVM Light 5.0: как пользоваться навигационной службой

    Более короткий синтаксис для кастинга из списка в список ?

    Изображение / Графика в форму

    Как выстроить два набора данных в Excel?

    Что эквивалентно C ++ Pair в Java?

    «Как» страница, использующая API-интерфейс Facebook Graph

    как вычислять среднее / медианное значение для каждой группы в кадре данных в r

    Давайте будем гением компьютера.