gSoap: how to gracefully shutdown the webservice a

2019-04-15 02:03发布

问题:

I'm using gSoap to write a webservice. It's running as a console application. In all gSoap examples I see, that requests are dispatched in infinite loop like for(;;;) even in multi-threaded version.

But how can I make my webservice to terminate gracefully when, say, user presses space on the console?

Preferably:

  1. stop accepting new connections;
  2. Serve existing ones;
  3. Exit from application

回答1:

The section 7.2.4 How to Create a Multi-Threaded Stand-Alone Service in the documentation has example code for writing an accept loop. You need to write your own accept loop and add signal handling so it responds to Ctrl-C.

  1. stop accepting new connections:

    Leave the loop so you stop calling accept.

  2. Serve existing ones:

    The threads need to inform you when they are finished, so you can exit when the number of active clients is zero. (boost::thead_group has a join_all which does exactly that.)

  3. Exit from application:



回答2:

The only solution I came up so far is using timeouts soap->recv_timeout = 20; soap->send_timeout = 20; soap->connect_timeout = 5; soap->accept_timeout = 5; Then all blocking functions return periodically. But this is not ideal for me, because I want to be able to terminate the app quickly even if there is an ongoing transmission, but at the same time, don't want to compromise reliability on a slow/flaky connection (it's an embedded device connected via GPRS).



回答3:

What you need to do is register signal handler so when you terminate your application using Ctrl + C, it calls you registered function where you can gracefully terminates.

e.g

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;
}