BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
XmlRpcServer.cpp
Go to the documentation of this file.
1
2#include "XmlRpcServer.h"
3#include "XmlRpcException.h"
6#include "XmlRpcSocket.h"
7#include "XmlRpcUtil.h"
8
9using namespace XmlRpc;
10
16
18 this->shutdown();
19 _methods.clear();
20 delete _listMethods;
21 delete _methodHelp;
22}
23
24// Add a command to the RPC server
26 _methods[method->name()] = method;
27}
28
29// Remove a command from the RPC server
31 MethodMap::iterator i = _methods.find( method->name() );
32 if ( i != _methods.end() ) _methods.erase( i );
33}
34
35// Remove a command from the RPC server by name
36void XmlRpcServer::removeMethod( const std::string& methodName ) {
37 MethodMap::iterator i = _methods.find( methodName );
38 if ( i != _methods.end() ) _methods.erase( i );
39}
40
41// Look up a method by name
42XmlRpcServerMethod* XmlRpcServer::findMethod( const std::string& name ) const {
43 MethodMap::const_iterator i = _methods.find( name );
44 if ( i == _methods.end() ) return 0;
45 return i->second;
46}
47
48// Create a socket, bind to the specified port, and
49// set it in listen mode to make it available for clients.
50bool XmlRpcServer::bindAndListen( int port, int backlog /*= 5*/ ) {
51 int fd = XmlRpcSocket::socket();
52 if ( fd < 0 )
53 {
54 XmlRpcUtil::error( "XmlRpcServer::bindAndListen: Could not create socket (%s).",
55 XmlRpcSocket::getErrorMsg().c_str() );
56 return false;
57 }
58
59 this->setfd( fd );
60
61 // Don't block on reads/writes
63 {
64 this->close();
66 "XmlRpcServer::bindAndListen: Could not set socket to non-blocking input mode (%s).",
67 XmlRpcSocket::getErrorMsg().c_str() );
68 return false;
69 }
70
71 // Allow this port to be re-bound immediately so server re-starts are not delayed
72 if ( !XmlRpcSocket::setReuseAddr( fd ) )
73 {
74 this->close();
76 "XmlRpcServer::bindAndListen: Could not set SO_REUSEADDR socket option (%s).",
77 XmlRpcSocket::getErrorMsg().c_str() );
78 return false;
79 }
80
81 // Bind to the specified port on the default interface
82 if ( !XmlRpcSocket::bind( fd, port ) )
83 {
84 this->close();
85 XmlRpcUtil::error( "XmlRpcServer::bindAndListen: Could not bind to specified port (%s).",
86 XmlRpcSocket::getErrorMsg().c_str() );
87 return false;
88 }
89
90 // Set in listening mode
91 if ( !XmlRpcSocket::listen( fd, backlog ) )
92 {
93 this->close();
95 "XmlRpcServer::bindAndListen: Could not set socket in listening mode (%s).",
96 XmlRpcSocket::getErrorMsg().c_str() );
97 return false;
98 }
99
100 XmlRpcUtil::log( 2, "XmlRpcServer::bindAndListen: server listening on port %d fd %d", port,
101 fd );
102
103 // Notify the dispatcher to listen on this source when we are in work()
104 _disp.addSource( this, XmlRpcDispatch::ReadableEvent );
105
106 return true;
107}
108
109// Process client requests for the specified time
110void XmlRpcServer::work( double msTime ) {
111 XmlRpcUtil::log( 2, "XmlRpcServer::work: waiting for a connection" );
112 _disp.work( msTime );
113}
114
115// Handle input on the server socket by accepting the connection
116// and reading the rpc request.
117unsigned XmlRpcServer::handleEvent( unsigned mask ) {
119 return XmlRpcDispatch::ReadableEvent; // Continue to monitor this fd
120}
121
122// Accept a client connection request and create a connection to
123// handle method calls from the client.
125 int s = XmlRpcSocket::accept( this->getfd() );
126 XmlRpcUtil::log( 2, "XmlRpcServer::acceptConnection: socket %d", s );
127 if ( s < 0 )
128 {
129 // this->close();
130 XmlRpcUtil::error( "XmlRpcServer::acceptConnection: Could not accept connection (%s).",
131 XmlRpcSocket::getErrorMsg().c_str() );
132 }
133 else if ( !XmlRpcSocket::setNonBlocking( s ) )
134 {
136 XmlRpcUtil::error( "XmlRpcServer::acceptConnection: Could not set socket to non-blocking "
137 "input mode (%s).",
138 XmlRpcSocket::getErrorMsg().c_str() );
139 }
140 else // Notify the dispatcher to listen for input on this source when we are in work()
141 {
142 XmlRpcUtil::log( 2, "XmlRpcServer::acceptConnection: creating a connection" );
144 }
145}
146
147// Create a new connection object for processing requests from a specific client.
149 // Specify that the connection object be deleted when it is closed
150 return new XmlRpcServerConnection( s, this, true );
151}
152
154
155// Stop processing client requests
156void XmlRpcServer::exit() { _disp.exit(); }
157
158// Close the server socket file descriptor and stop monitoring connections
160 // This closes and destroys all connections as well as closing this socket
161 _disp.clear();
162}
163
164// Introspection support
165static const std::string LIST_METHODS( "system.listMethods" );
166static const std::string METHOD_HELP( "system.methodHelp" );
167static const std::string MULTICALL( "system.multicall" );
168
169// List all methods available on a server
171public:
173
174 void execute( XmlRpcValue& params, XmlRpcValue& result ) { _server->listMethods( result ); }
175
176 std::string help() {
177 return std::string( "List all methods available on a server as an array of strings" );
178 }
179};
180
181// Retrieve the help string for a named method
183public:
185
186 void execute( XmlRpcValue& params, XmlRpcValue& result ) {
187 if ( params[0].getType() != XmlRpcValue::TypeString )
188 throw XmlRpcException( METHOD_HELP + ": Invalid argument type" );
189
190 XmlRpcServerMethod* m = _server->findMethod( params[0] );
191 if ( !m ) throw XmlRpcException( METHOD_HELP + ": Unknown method name" );
192
193 result = m->help();
194 }
195
196 std::string help() { return std::string( "Retrieve the help string for a named method" ); }
197};
198
199// Specify whether introspection is enabled or not. Default is enabled.
201 if ( _introspectionEnabled == enabled ) return;
202
203 _introspectionEnabled = enabled;
204
205 if ( enabled )
206 {
207 if ( !_listMethods )
208 {
209 _listMethods = new ListMethods( this );
210 _methodHelp = new MethodHelp( this );
211 }
212 else
213 {
216 }
217 }
218 else
219 {
220 removeMethod( LIST_METHODS );
221 removeMethod( METHOD_HELP );
222 }
223}
224
226 int i = 0;
227 result.setSize( _methods.size() + 1 );
228 for ( MethodMap::iterator it = _methods.begin(); it != _methods.end(); ++it )
229 result[i++] = it->first;
230
231 // Multicall support is built into XmlRpcServerConnection
232 result[i] = MULTICALL;
233}
XmlRpcServer s
void execute(XmlRpcValue &params, XmlRpcValue &result)
Execute the method. Subclasses must provide a definition for this method.
ListMethods(XmlRpcServer *s)
std::string help()
MethodHelp(XmlRpcServer *s)
std::string help()
void execute(XmlRpcValue &params, XmlRpcValue &result)
Execute the method. Subclasses must provide a definition for this method.
@ ReadableEvent
data available to read
A class to handle XML RPC requests from a particular client.
Abstract class representing a single RPC method.
virtual std::string help()
std::string & name()
Returns the name of the method.
XmlRpcServerMethod(std::string const &name, XmlRpcServer *server=0)
Constructor.
A class to handle XML RPC requests.
void shutdown()
Close all connections with clients and the socket file descriptor.
XmlRpcServerMethod * _listMethods
bool bindAndListen(int port, int backlog=5)
void enableIntrospection(bool enabled=true)
Specify whether introspection is enabled or not. Default is not enabled.
XmlRpcServer()
Create a server object.
void removeMethod(XmlRpcServerMethod *method)
Remove a command from the RPC server.
virtual void removeConnection(XmlRpcServerConnection *)
Remove a connection from the dispatcher.
virtual XmlRpcServerConnection * createConnection(int socket)
Create a new connection object for processing requests from a specific client.
XmlRpcServerMethod * _methodHelp
virtual unsigned handleEvent(unsigned eventType)
Handle client connection requests.
void addMethod(XmlRpcServerMethod *method)
Add a command to the RPC server.
XmlRpcServerMethod * findMethod(const std::string &name) const
Look up a method by name.
void work(double msTime)
Process client requests for the specified time.
virtual ~XmlRpcServer()
Destructor.
virtual void acceptConnection()
Accept a client connection request.
void listMethods(XmlRpcValue &result)
Introspection support.
void exit()
Temporarily stop processing client requests and exit the work() method.
XmlRpcDispatch _disp
static int socket()
Creates a stream (TCP) socket. Returns -1 on failure.
static bool listen(int socket, int backlog)
Set socket in listen mode.
static int accept(int socket)
Accept a client connection request.
static bool setReuseAddr(int socket)
static bool setNonBlocking(int socket)
Sets a stream (TCP) socket to perform non-blocking IO. Returns false on failure.
static void close(int socket)
Closes a socket.
static bool bind(int socket, int port)
Bind to a specified port.
static std::string getErrorMsg()
Returns message corresponding to last error.
virtual void close()
int getfd() const
Return the file descriptor being monitored.
void setfd(int fd)
Specify the file descriptor to monitor.
static void error(const char *fmt,...)
Dump error messages somewhere.
static void log(int level, const char *fmt,...)
Dump messages somewhere.
RPC method arguments and results are represented by Values.
Definition XmlRpcValue.h:22
void setSize(int size)
Specify the size for array values. Array values will grow beyond this size if needed.