From e833d990db1ec6efa70c54c3de0b53c8651d3724 Mon Sep 17 00:00:00 2001 From: amass <168062547@qq.com> Date: Sun, 10 Nov 2024 20:23:00 +0800 Subject: [PATCH] make command not block. --- Server/Application.cpp | 8 ++- Server/main.cpp | 160 +++++++++++++++++++++-------------------- 2 files changed, 88 insertions(+), 80 deletions(-) diff --git a/Server/Application.cpp b/Server/Application.cpp index e876d31..fb5e0eb 100644 --- a/Server/Application.cpp +++ b/Server/Application.cpp @@ -349,7 +349,13 @@ void Application::requetExit() { nng_log_set_logger(nng_stderr_logger); LOG(info) << "send exit request to program."; Nng::Socket request(Nng::Request); - request.dial(IpcUrl); + request.setOption(Nng::RecvTimeout, std::chrono::milliseconds(2000)); + std::error_code error; + request.dial(IpcUrl, error); + if (error) { + LOG(error) << error.message(); + return; + } boost::json::object object; object["command"] = "exit"; diff --git a/Server/main.cpp b/Server/main.cpp index 162f221..3a6f6f6 100644 --- a/Server/main.cpp +++ b/Server/main.cpp @@ -32,87 +32,89 @@ int main(int argc, char const *argv[]) { try { boost::program_options::store(boost::program_options::parse_command_line(argc, argv, description), values); boost::program_options::notify(values); + + if (values.count("help")) { + std::cout << description << std::endl; + std::exit(0); + } else if (values.count("exit")) { + Application::requetExit(); + std::exit(0); + } + + std::error_code error; + auto prefix = std::filesystem::current_path(error); + if (error) { + LOG(fatal) << "cannot get current path,reason: " << error.message(); + return -1; + } + + if (values.count("prefix")) { + prefix = values["prefix"].as(); + if (prefix.empty() || !std::filesystem::exists(prefix)) { + LOG(fatal) << "working directory: " << prefix << " is not exists."; + return -1; + } + std::filesystem::current_path(prefix, error); + LOG_IF(fatal, error) << "cannot set current path,reason: " << error.message(); + } + + auto application = Singleton::instance("settings.ini"); + + auto database = Singleton::instance(); + database->open(application->getSqlte3Path()); + + if (!std::filesystem::exists(application->getDocumentRoot())) { + LOG(fatal) << "document root: " << application->getDocumentRoot() << " is not exists..."; + std::exit(102); + } + BOOST_ASSERT_MSG(!application->getServer().empty(), "server.empty() == true"); + + auto address = boost::asio::ip::make_address(application->getServer()); + auto listener = std::make_shared(application->ioContext(), + boost::asio::ip::tcp::endpoint{address, application->getPort()}); + listener->startAccept(); + + auto wechatContext = Singleton::instance(application->ioContext()); + auto corpContext = Singleton::instance(application->ioContext()); + corpContext->start(); + auto live2d = std::make_shared(); + + LOG(info) << "hardware_concurrency: " << std::thread::hardware_concurrency() + << ",threads: " << application->getThreads(); + LOG(info) << "working directory: " << prefix.generic_string(); + LOG(info) << "server: " << application->getServer() << ",port: " << application->getPort(); + LOG(info) << "document root: " << application->getDocumentRoot(); + + // Capture SIGINT and SIGTERM to perform a clean shutdown +#ifndef WIN32 + boost::asio::signal_set signals(application->ioContext(), SIGINT, SIGTERM, SIGHUP); +#else + boost::asio::signal_set signals(application->ioContext(), SIGINT, SIGTERM); +#endif + signals.add(SIGUSR1); + signals.async_wait([&application](boost::system::error_code const &, int signal) { + // Stop the io_context. This will cause run() + // to return immediately, eventually destroying the + // io_context and any remaining handlers in it. + LOG(info) << "capture " << (signal == SIGINT ? "SIGINT" : "SIGTERM") << ",stop!"; + application->ioContext().stop(); + }); + + auto udpServer = std::make_shared(application->ioContext()); + auto mediaServer = std::make_shared(554, false); + auto webApp = std::make_unique(); + + using namespace boost::asio::ip; + auto proxyAddress = make_address(application->getServer()); + uint16_t proxyPort = 41091; + auto proxy = std::make_shared(application->ioContext(), tcp::endpoint{proxyAddress, proxyPort}); + boost::system::error_code perror; + proxy->run(perror); + return application->exec(); } catch (const boost::program_options::invalid_command_line_syntax &e) { LOG(fatal) << e.what(); std::exit(-1); + } catch (const std::exception &e) { + LOG(error) << e.what(); } - - if (values.count("help")) { - std::cout << description << std::endl; - std::exit(0); - } else if (values.count("exit")) { - Application::requetExit(); - std::exit(0); - } - - std::error_code error; - auto prefix = std::filesystem::current_path(error); - if (error) { - LOG(fatal) << "cannot get current path,reason: " << error.message(); - return -1; - } - - if (values.count("prefix")) { - prefix = values["prefix"].as(); - if (prefix.empty() || !std::filesystem::exists(prefix)) { - LOG(fatal) << "working directory: " << prefix << " is not exists."; - return -1; - } - std::filesystem::current_path(prefix, error); - LOG_IF(fatal, error) << "cannot set current path,reason: " << error.message(); - } - - auto application = Singleton::instance("settings.ini"); - - auto database = Singleton::instance(); - database->open(application->getSqlte3Path()); - - if (!std::filesystem::exists(application->getDocumentRoot())) { - LOG(fatal) << "document root: " << application->getDocumentRoot() << " is not exists..."; - std::exit(102); - } - BOOST_ASSERT_MSG(!application->getServer().empty(), "server.empty() == true"); - - auto address = boost::asio::ip::make_address(application->getServer()); - auto listener = std::make_shared(application->ioContext(), - boost::asio::ip::tcp::endpoint{address, application->getPort()}); - listener->startAccept(); - - auto wechatContext = Singleton::instance(application->ioContext()); - auto corpContext = Singleton::instance(application->ioContext()); - corpContext->start(); - auto live2d = std::make_shared(); - - LOG(info) << "hardware_concurrency: " << std::thread::hardware_concurrency() - << ",threads: " << application->getThreads(); - LOG(info) << "working directory: " << prefix.generic_string(); - LOG(info) << "server: " << application->getServer() << ",port: " << application->getPort(); - LOG(info) << "document root: " << application->getDocumentRoot(); - - // Capture SIGINT and SIGTERM to perform a clean shutdown -#ifndef WIN32 - boost::asio::signal_set signals(application->ioContext(), SIGINT, SIGTERM, SIGHUP); -#else - boost::asio::signal_set signals(application->ioContext(), SIGINT, SIGTERM); -#endif - signals.add(SIGUSR1); - signals.async_wait([&application](boost::system::error_code const &, int signal) { - // Stop the io_context. This will cause run() - // to return immediately, eventually destroying the - // io_context and any remaining handlers in it. - LOG(info) << "capture " << (signal == SIGINT ? "SIGINT" : "SIGTERM") << ",stop!"; - application->ioContext().stop(); - }); - - auto udpServer = std::make_shared(application->ioContext()); - auto mediaServer = std::make_shared(554, false); - auto webApp = std::make_unique(); - - using namespace boost::asio::ip; - auto proxyAddress = make_address(application->getServer()); - uint16_t proxyPort = 41091; - auto proxy = std::make_shared(application->ioContext(), tcp::endpoint{proxyAddress, proxyPort}); - boost::system::error_code perror; - proxy->run(perror); - return application->exec(); } \ No newline at end of file