简体   繁体   English

如何正常停止使用nghttp2 asio构建的HTTP2服务器

[英]How to gracefully stop a HTTP2 server built with nghttp2 asio

I am aware of how to use nghttp2 asio library to build HTTP2 server and client applications. 我知道如何使用nghttp2 asio库来构建HTTP2服务器和客户端应用程序。

The documentation says that there are stop and join APIs for gracefully stopping an HTTP2 server. 文档说,存在用于优雅地停止HTTP2服务器的stopjoin API。

Is there any working example of using stop and join ? 有使用stopjoin工作示例吗? In particular, as soon as listen_and_serve is called, the thread goes to a busy loop. 特别是,一旦调用listen_and_serve ,线程就会进入繁忙循环。 Is it recommended to call stop from a different thread? 是否建议从其他线程调用stop Unfortunately no clue or example code is given in the documentation. 不幸的是,文档中未提供任何线索或示例代码。

EDIT: 编辑:

Here is a working program where I am trying to stop the server on SIGINT . 这是一个正在运行的程序,我试图在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;
  }
}

The execution hangs at myserver.stop() after pressing Control+C . 按下Control+C后,执行将挂在myserver.stop() I tried using only myserver.stop() or myserver.join() but without any improvement. 我尝试仅使用myserver.stop()myserver.join()但没有任何改进。 If I directly call exit(0) like below, the server stops with a segmentation fault. 如果像下面这样直接调用exit(0) ,则服务器会因分段错误而停止。

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

Any help is appreciated. 任何帮助表示赞赏。

The asynchronous parameter in listen_and_serve should be set to true , default is asynchronous = false . 应该将listen_and_serveasynchronous参数设置为true ,默认值为asynchronous = false

Note that the server will not exit and wait on the myserver.join() until the last client connection is closed. 请注意,直到最后一个客户端连接关闭,服务器才会退出并在myserver.join()上等待。 When you call myserver.close() , the server stops accepting new connections. 当您调用myserver.close() ,服务器停止接受新连接。

A working solution below: 以下工作解决方案:

#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();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM