gSoap を使用して Web サービスを作成しています。コンソール アプリケーションとして実行されます。私が見るすべてのgSoapの例では、リクエストはマルチスレッドバージョンでも for(;;;) のような無限ループでディスパッチされます。
しかし、たとえばユーザーがコンソールのスペースを押したときに、Web サービスを正常に終了させるにはどうすればよいでしょうか?
好ましい:
- 新しい接続の受け入れを停止します。
- 既存のものを提供します。
- アプリケーションを終了する
gSoap を使用して Web サービスを作成しています。コンソール アプリケーションとして実行されます。私が見るすべてのgSoapの例では、リクエストはマルチスレッドバージョンでも for(;;;) のような無限ループでディスパッチされます。
しかし、たとえばユーザーがコンソールのスペースを押したときに、Web サービスを正常に終了させるにはどうすればよいでしょうか?
好ましい:
これまでに思いついた唯一の解決策は、タイムアウトを使用することです soap->recv_timeout = 20; soap->send_timeout = 20; soap->connect_timeout = 5; soap->accept_timeout = 5; その後、すべてのブロッキング関数が定期的に戻ります。しかし、これは私にとって理想的ではありません。送信が進行中の場合でもアプリをすばやく終了できるようにしたいと同時に、低速/不安定な接続で信頼性を妥協したくないからです (これは組み込みのGPRS 経由で接続されたデバイス)。
ドキュメントのセクション7.2.4 マルチスレッド スタンドアロン サービスの作成方法には、accept ループを記述するためのサンプル コードがあります。Ctrl-C に応答するように、独自の受け入れループを作成し、シグナル処理を追加する必要があります。
新しい接続の受け入れを停止します:
ループを終了して、accept の呼び出しを停止します。
既存のものを提供する:
スレッドは終了時に通知する必要があるため、アクティブなクライアントの数がゼロになったときに終了できます。(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;
}