gSoap: как изящно завершить работу приложения веб-сервиса? - PullRequest
1 голос
/ 09 марта 2011

Я использую gSoap для написания веб-сервиса. Он работает как консольное приложение. Во всех примерах gSoap я вижу, что запросы отправляются в бесконечном цикле, как for (;;;), даже в многопоточной версии.

Но как мне сделать так, чтобы мой веб-сервис корректно завершал работу, когда, скажем, пользователь нажимает пространство на консоли?

Предпочтительно:

  1. прекратить прием новых подключений;
  2. обслуживать существующих;
  3. Выход из приложения

Ответы [ 3 ]

3 голосов
/ 08 мая 2014

Единственное решение, которое я до сих пор придумал, это использование тайм-аутов soap-> recv_timeout = 20; soap-> send_timeout = 20; soap-> connect_timeout = 5; soap-> accept_timeout = 5; Затем все функции блокировки периодически возвращаются. Но это не идеально для меня, потому что я хочу иметь возможность быстро завершать работу приложения, даже если идет непрерывная передача, но в то же время не хочу ставить под угрозу надежность медленного / нестабильного соединения (это встроенное устройство подключено через GPRS).

2 голосов
/ 26 марта 2011

В разделе 7.2.4 Как создать многопоточную автономную службу в документации приведен пример кода для написания цикла принятия. Вам нужно написать собственный цикл принятия и добавить обработку сигнала, чтобы он реагировал на Ctrl-C.

  1. прекратить прием новых подключений:

    Выйти из цикла, чтобы прекратить звонить, принять.

  2. Обслуживание существующих:

    Потоки должны информировать вас о завершении, чтобы вы могли выйти, когда число активных клиентов равно нулю. (boost :: thead_group имеет join_all, который делает именно это.)

  3. Выход из приложения:

0 голосов
/ 26 марта 2011

Что вам нужно сделать, это зарегистрировать обработчик сигнала, чтобы при завершении работы приложения с помощью сочетания клавиш Ctrl + C он вызывал зарегистрированную функцию, которую вы можете корректно завершить.

* 1003 например *

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