pstream_inetd_server.cpp 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. /* A simple standalone RPC server based on an Xmlrpc-c packet socket.
  2. This program expects the invoker to provide an established connection
  3. to a client as Standard Input (E.g. Inetd can do this). It processes
  4. RPCs from that connection until the client closes the connection.
  5. This is not an XML-RPC server, because it uses a simple packet socket
  6. instead of HTTP. See xmlrpc_sample_add_server.cpp for an example of
  7. an XML-RPC server.
  8. The advantage of this example over XML-RPC is that it has a connection
  9. concept. The client can be connected indefinitely and the server gets
  10. notified when the client terminates, even if it gets aborted by its OS.
  11. Here's an example of running this:
  12. $ socketexec -accept -local_port=8080 ./pstream_inetd_server
  13. */
  14. #ifndef WIN32
  15. #include <unistd.h>
  16. #endif
  17. #include <cassert>
  18. #include <iostream>
  19. #include <signal.h>
  20. #include <xmlrpc-c/base.hpp>
  21. #include <xmlrpc-c/registry.hpp>
  22. #include <xmlrpc-c/server_pstream.hpp>
  23. using namespace std;
  24. class sampleAddMethod : public xmlrpc_c::method {
  25. public:
  26. sampleAddMethod() {
  27. // signature and help strings are documentation -- the client
  28. // can query this information with a system.methodSignature and
  29. // system.methodHelp RPC.
  30. this->_signature = "i:ii"; // method's arguments are two integers
  31. this->_help = "This method adds two integers together";
  32. }
  33. void
  34. execute(xmlrpc_c::paramList const& paramList,
  35. xmlrpc_c::value * const retvalP) {
  36. int const addend(paramList.getInt(0));
  37. int const adder(paramList.getInt(1));
  38. paramList.verifyEnd(2);
  39. *retvalP = xmlrpc_c::value_int(addend + adder);
  40. }
  41. };
  42. int
  43. main(int const,
  44. const char ** const) {
  45. // It's a good idea to disable SIGPIPE signals; if client closes his end
  46. // of the pipe/socket, we'd rather see a failure to send a response than
  47. // get killed by the OS.
  48. signal(SIGPIPE, SIG_IGN);
  49. try {
  50. xmlrpc_c::registry myRegistry;
  51. xmlrpc_c::methodPtr const sampleAddMethodP(new sampleAddMethod);
  52. myRegistry.addMethod("sample.add", sampleAddMethodP);
  53. xmlrpc_c::serverPstreamConn server(
  54. xmlrpc_c::serverPstreamConn::constrOpt()
  55. .socketFd(STDIN_FILENO)
  56. .registryP(&myRegistry));
  57. server.run();
  58. } catch (exception const& e) {
  59. cerr << "Something threw an error: " << e.what() << endl;
  60. }
  61. return 0;
  62. }