Loading ...
Sorry, an error occurred while loading the content.

Respond without 'return' from SOAP::Transport::HTTP::Daemon?

Expand Messages
  • Greg Owen
    Short version: I have a SOAP::Transport::HTTP::Daemon server which I would like to gracefully exit upon receiving the proper method call from a remote client.
    Message 1 of 2 , May 25 9:14 AM
    • 0 Attachment
      Short version:

      I have a SOAP::Transport::HTTP::Daemon server which I would like to
      gracefully exit upon receiving the proper method call from a remote
      client.

      If the server method does a "die SOAP::Fault...", the fault is returned
      but the server process doesn't exit.

      If the server method does an "exit;", the client gets killed with a
      transport error. I tried using on_fault to catch it in the client, but
      that doesn't work. I can catch it by putting the method call within an
      eval {} block, but that seems like a kludge.

      Is there a way to have the server manually send back a response, then exit
      without returning, so that the server exits and the client gets a
      reasonable response?


      Long version:

      Given a server like this:

      === begin testserver.pl ===============================
      #!perl -w

      use SOAP::Transport::HTTP;

      $daemon = SOAP::Transport::HTTP::Daemon
      -> new (LocalPort => 80)
      -> dispatch_to('Demo');

      print "Connect to SOAP server at ", $daemon->url, "\n";
      $daemon->handle;

      package Demo;

      sub hello {
      return (1, "Hello!");
      }

      sub goodbye {
      ### This returns a polite fault, but doesn't exit the server.
      #die SOAP::Fault
      # ->faultcode('My.Server')
      # ->faultstring('Goodbye, cruel world!');

      # This exits the server, but looks like an error
      # on the client end:
      exit;
      }
      === end testserver.pl =================================

      And a client like this:

      === begin testclient.pl ===============================
      #!perl

      use SOAP::Lite +trace => [qw(transport method fault)];

      $soap_response = SOAP::Lite
      -> uri('http://proc1/Demo')
      -> proxy('http://proc1/')
      -> hello();

      $soap_response = SOAP::Lite
      -> uri('http://proc1/Demo')
      -> proxy('http://proc1/')
      -> goodbye();

      print STDERR "We have gotten past the goodbye() method call\n";
      === end testclient.pl =================================

      I get the following trace on the client side:

      === debug output ======================================
      C:\dev>testclient.pl
      SOAP::Serializer::envelope: hello
      SOAP::Transport::HTTP::Client::send_receive: HTTP::Request=HASH(0x1da59e0)
      SOAP::Transport::HTTP::Client::send_receive:
      HTTP::Response=HASH(0x1f9ac48)
      SOAP::Serializer::envelope: goodbye
      SOAP::Transport::HTTP::Client::send_receive: HTTP::Request=HASH(0x20989b4)
      SOAP::Transport::HTTP::Client::send_receive:
      HTTP::Response=HASH(0x1d6dff4)
      Unexpected Content-Type '' returned

      C:\dev>
      === debug output ======================================


      Any help is appreciated. Like I said, I can make it work with an eval
      block, but I'd prefer to use a more elegant solution.

      --
      gowen -- Greg Owen -- gowen@...
      79A7 4063 96B6 9974 86CA 3BEF 521C 860F 5A93 D66D
    • Byrne Reese
      The only thing I might suggest is to execute a system() command that will sleep and then kill a specific process id. You need something that will fork out of
      Message 2 of 2 , Oct 20, 2004
      • 0 Attachment
        The only thing I might suggest is to execute a system() command that
        will sleep and then kill a specific process id. You need something that
        will fork out of the existing process so that the current process is
        allowed to return a response, and then die. Because Perl is not
        inherently multi-threaded, I can think of no way to do this off the top
        of my head without breaking out of the current process somehow.

        Greg Owen wrote:

        >
        > Short version:
        >
        > I have a SOAP::Transport::HTTP::Daemon server which I would like to
        > gracefully exit upon receiving the proper method call from a remote
        > client.
        >
        > If the server method does a "die SOAP::Fault...", the fault is returned
        > but the server process doesn't exit.
        >
        > If the server method does an "exit;", the client gets killed with a
        > transport error. I tried using on_fault to catch it in the client, but
        > that doesn't work. I can catch it by putting the method call within an
        > eval {} block, but that seems like a kludge.
        >
        > Is there a way to have the server manually send back a response, then
        > exit
        > without returning, so that the server exits and the client gets a
        > reasonable response?
        >
        >
        > Long version:
        >
        > Given a server like this:
        >
        > === begin testserver.pl ===============================
        > #!perl -w
        >
        > use SOAP::Transport::HTTP;
        >
        > $daemon = SOAP::Transport::HTTP::Daemon
        > -> new (LocalPort => 80)
        > -> dispatch_to('Demo');
        >
        > print "Connect to SOAP server at ", $daemon->url, "\n";
        > $daemon->handle;
        >
        > package Demo;
        >
        > sub hello {
        > return (1, "Hello!");
        > }
        >
        > sub goodbye {
        > ### This returns a polite fault, but doesn't exit the server.
        > #die SOAP::Fault
        > # ->faultcode('My.Server')
        > # ->faultstring('Goodbye, cruel world!');
        >
        > # This exits the server, but looks like an error
        > # on the client end:
        > exit;
        > }
        > === end testserver.pl =================================
        >
        > And a client like this:
        >
        > === begin testclient.pl ===============================
        > #!perl
        >
        > use SOAP::Lite +trace => [qw(transport method fault)];
        >
        > $soap_response = SOAP::Lite
        > -> uri('http://proc1/Demo') <http://proc1/Demo%27%29>
        > -> proxy('http://proc1/') <http://proc1/%27%29>
        > -> hello();
        >
        > $soap_response = SOAP::Lite
        > -> uri('http://proc1/Demo') <http://proc1/Demo%27%29>
        > -> proxy('http://proc1/') <http://proc1/%27%29>
        > -> goodbye();
        >
        > print STDERR "We have gotten past the goodbye() method call\n";
        > === end testclient.pl =================================
        >
        > I get the following trace on the client side:
        >
        > === debug output ======================================
        > C:\dev>testclient.pl
        > SOAP::Serializer::envelope: hello
        > SOAP::Transport::HTTP::Client::send_receive: HTTP::Request=HASH(0x1da59e0)
        > SOAP::Transport::HTTP::Client::send_receive:
        > HTTP::Response=HASH(0x1f9ac48)
        > SOAP::Serializer::envelope: goodbye
        > SOAP::Transport::HTTP::Client::send_receive: HTTP::Request=HASH(0x20989b4)
        > SOAP::Transport::HTTP::Client::send_receive:
        > HTTP::Response=HASH(0x1d6dff4)
        > Unexpected Content-Type '' returned
        >
        > C:\dev>
        > === debug output ======================================
        >
        >
        > Any help is appreciated. Like I said, I can make it work with an eval
        > block, but I'd prefer to use a more elegant solution.
        >
        > --
        > gowen -- Greg Owen -- gowen@...
        > 79A7 4063 96B6 9974 86CA 3BEF 521C 860F 5A93 D66D
      Your message has been successfully submitted and would be delivered to recipients shortly.