我正在使用 gSoap 编写网络服务。它作为控制台应用程序运行。在我看到的所有 gSoap 示例中,即使在多线程版本中,请求也会像 for(;;;) 这样在无限循环中分派。
但是,当用户按下控制台上的空格键时,如何让我的 Web 服务正常终止?
最好:
- 停止接受新连接;
- 服务现有的;
- 退出应用程序
我正在使用 gSoap 编写网络服务。它作为控制台应用程序运行。在我看到的所有 gSoap 示例中,即使在多线程版本中,请求也会像 for(;;;) 这样在无限循环中分派。
但是,当用户按下控制台上的空格键时,如何让我的 Web 服务正常终止?
最好:
到目前为止我想出的唯一解决方案是使用超时soap->recv_timeout = 20; 肥皂->send_timeout = 20;肥皂->连接超时= 5;肥皂->接受超时= 5;然后所有阻塞函数定期返回。但这对我来说并不理想,因为即使有正在进行的传输,我也希望能够快速终止应用程序,但同时,不想在缓慢/不稳定的连接上损害可靠性(它是嵌入式通过 GPRS 连接的设备)。
文档中的7.2.4 如何创建多线程独立服务部分有编写接受循环的示例代码。您需要编写自己的接受循环并添加信号处理,以便它响应 Ctrl-C。
停止接受新连接:
离开循环,这样你就停止调用接受。
服务现有的:
线程需要在完成时通知您,因此您可以在活动客户端数量为零时退出。( boost::thead_group 有一个 join_all 正是这样做的。)
退出应用程序:
您需要做的是注册信号处理程序,因此当您使用 Ctrl + C 终止应用程序时,它会调用您注册的函数,您可以在其中优雅地终止。
例如
class gsoap_test {
public:
void start() {
running_ = true;
while(running_) {
//gsoap threads
}
//stop and cleanup
}
void stop() {
running_ = false;
}
private:
bool running_;
};
//global variable
gsoap_test gsoap;
void sighandler(int sig)
{
std::cout<< "Signal caught..." << std::endl;
//Stop gracefully here
gsoap.stop();
exit(0);
}
int main(int argc, char** argv) {
//register signal
signal(SIGABRT, &sighandler);
signal(SIGTERM, &sighandler);
signal(SIGINT, &sighandler);
gsoap.start();
return EXIT_SUCCESS;
}