Как изящно остановить сервер HTTP2, созданный с помощью nghttp2 asio - PullRequest
0 голосов
/ 01 ноября 2018

Я знаю, как использовать nghttp2 библиотеку asio для создания HTTP2-сервера и клиентских приложений.

В документации говорится, что есть API stop и join для изящной остановки сервера HTTP2.

Есть ли рабочий пример использования stop и join? В частности, как только вызывается listen_and_serve, поток переходит в занятый цикл. Рекомендуется ли вызывать stop из другого потока? К сожалению, в документации нет подсказки или примера кода.

EDIT:

Вот рабочая программа, в которой я пытаюсь остановить сервер на SIGINT.

#include <iostream>
#include <thread>
#include <nghttp2/asio_http2_server.h>

using namespace nghttp2::asio_http2;
using namespace nghttp2::asio_http2::server;

nghttp2::asio_http2::server::http2 myserver;
void signalHandler( int signum ) {
  std::cout << "Interrupt signal (" << signum << ") received." << std::endl;
  myserver.stop();
  myserver.join();
  exit(0);
}

int main(int argc, char *argv[]) {
  signal(SIGINT, signalHandler);
  std::thread::id this_id = std::this_thread::get_id();
  std::cout << "Main thread running at " << this_id << std::endl;
  boost::system::error_code ec;

  myserver.handle("/api/ping", [](const request &req, const response &res) {
    std::thread::id this_id = std::this_thread::get_id();
    std::cout << "Ping Request received at " << this_id << std::endl;
    req.on_data([](const uint8_t *data, std::size_t len){
      std::cerr.write(reinterpret_cast<const char *>(data), len);
      std::cerr << std::endl;
    });
    res.write_head(200);
    res.end("hello, ping\n");
  });

  if (myserver.listen_and_serve(ec, "0.0.0.0", "8080")) {
    std::cerr << "error: " << ec.message() << std::endl;
  }
}

Выполнение зависает на myserver.stop() после нажатия Control+C. Я пытался использовать только myserver.stop() или myserver.join(), но без каких-либо улучшений. Если я напрямую позвоню exit(0), как показано ниже, сервер остановится с ошибкой сегментации.

void signalHandler( int signum ) {
  std::cout << "Interrupt signal (" << signum << ") received." << std::endl;
  myserver.stop();
  myserver.join();
  exit(0);
}

Любая помощь приветствуется.

1 Ответ

0 голосов
/ 09 ноября 2018

Параметр asynchronous в listen_and_serve должен быть установлен на true, по умолчанию asynchronous = false.

Обратите внимание, что сервер не будет выходить и ждать на myserver.join(), пока не будет закрыто последнее клиентское соединение. Когда вы звоните myserver.close(), сервер прекращает принимать новые соединения.

Рабочий раствор ниже:

#include <iostream>
#include <thread>
#include <nghttp2/asio_http2_server.h>

using namespace nghttp2::asio_http2;
using namespace nghttp2::asio_http2::server;

nghttp2::asio_http2::server::http2 myserver;
void signalHandler( int signum ) {
  std::cout << "Interrupt signal (" << signum << ") received." << std::endl;
  myserver.stop();
}

int main(int argc, char *argv[]) {
  signal(SIGINT, signalHandler);
  std::thread::id this_id = std::this_thread::get_id();
  boost::system::error_code ec;

  myserver.handle("/api/ping", [](const request &req, const response &res) {
    std::thread::id this_id = std::this_thread::get_id();
    std::cout << "Ping Request received at " << this_id << std::endl;
    req.on_data([](const uint8_t *data, std::size_t len){
      std::cerr.write(reinterpret_cast<const char *>(data), len);
      std::cerr << std::endl;
    });
    res.write_head(200);
    res.end("hello, ping\n");
  });

  if (myserver.listen_and_serve(ec, "0.0.0.0", "8080", true)) {
    std::cerr << "error: " << ec.message() << std::endl;
  }
  myserver.join();
}
...