CGEM BOSS 6.6.5.h
BESIII Offline Software System
Loading...
Searching...
No Matches
XmlRpcServer.cpp
Go to the documentation of this file.
1
2#include "XmlRpcServer.h"
5#include "XmlRpcSocket.h"
6#include "XmlRpcUtil.h"
7#include "XmlRpcException.h"
8
9
10using namespace XmlRpc;
11
12
19
20
22{
23 this->shutdown();
24 _methods.clear();
25 delete _listMethods;
26 delete _methodHelp;
27}
28
29
30// Add a command to the RPC server
31void
33{
34 _methods[method->name()] = method;
35}
36
37// Remove a command from the RPC server
38void
40{
41 MethodMap::iterator i = _methods.find(method->name());
42 if (i != _methods.end())
43 _methods.erase(i);
44}
45
46// Remove a command from the RPC server by name
47void
48XmlRpcServer::removeMethod(const std::string& methodName)
49{
50 MethodMap::iterator i = _methods.find(methodName);
51 if (i != _methods.end())
52 _methods.erase(i);
53}
54
55
56// Look up a method by name
58XmlRpcServer::findMethod(const std::string& name) const
59{
60 MethodMap::const_iterator i = _methods.find(name);
61 if (i == _methods.end())
62 return 0;
63 return i->second;
64}
65
66
67// Create a socket, bind to the specified port, and
68// set it in listen mode to make it available for clients.
69bool
70XmlRpcServer::bindAndListen(int port, int backlog /*= 5*/)
71{
72 int fd = XmlRpcSocket::socket();
73 if (fd < 0)
74 {
75 XmlRpcUtil::error("XmlRpcServer::bindAndListen: Could not create socket (%s).", XmlRpcSocket::getErrorMsg().c_str());
76 return false;
77 }
78
79 this->setfd(fd);
80
81 // Don't block on reads/writes
83 {
84 this->close();
85 XmlRpcUtil::error("XmlRpcServer::bindAndListen: Could not set socket to non-blocking input mode (%s).", XmlRpcSocket::getErrorMsg().c_str());
86 return false;
87 }
88
89 // Allow this port to be re-bound immediately so server re-starts are not delayed
91 {
92 this->close();
93 XmlRpcUtil::error("XmlRpcServer::bindAndListen: Could not set SO_REUSEADDR socket option (%s).", XmlRpcSocket::getErrorMsg().c_str());
94 return false;
95 }
96
97 // Bind to the specified port on the default interface
98 if ( ! XmlRpcSocket::bind(fd, port))
99 {
100 this->close();
101 XmlRpcUtil::error("XmlRpcServer::bindAndListen: Could not bind to specified port (%s).", XmlRpcSocket::getErrorMsg().c_str());
102 return false;
103 }
104
105 // Set in listening mode
106 if ( ! XmlRpcSocket::listen(fd, backlog))
107 {
108 this->close();
109 XmlRpcUtil::error("XmlRpcServer::bindAndListen: Could not set socket in listening mode (%s).", XmlRpcSocket::getErrorMsg().c_str());
110 return false;
111 }
112
113 XmlRpcUtil::log(2, "XmlRpcServer::bindAndListen: server listening on port %d fd %d", port, fd);
114
115 // Notify the dispatcher to listen on this source when we are in work()
117
118 return true;
119}
120
121
122// Process client requests for the specified time
123void
124XmlRpcServer::work(double msTime)
125{
126 XmlRpcUtil::log(2, "XmlRpcServer::work: waiting for a connection");
127 _disp.work(msTime);
128}
129
130
131
132// Handle input on the server socket by accepting the connection
133// and reading the rpc request.
134unsigned
136{
138 return XmlRpcDispatch::ReadableEvent; // Continue to monitor this fd
139}
140
141
142// Accept a client connection request and create a connection to
143// handle method calls from the client.
144void
146{
147 int s = XmlRpcSocket::accept(this->getfd());
148 XmlRpcUtil::log(2, "XmlRpcServer::acceptConnection: socket %d", s);
149 if (s < 0)
150 {
151 //this->close();
152 XmlRpcUtil::error("XmlRpcServer::acceptConnection: Could not accept connection (%s).", XmlRpcSocket::getErrorMsg().c_str());
153 }
154 else if ( ! XmlRpcSocket::setNonBlocking(s))
155 {
157 XmlRpcUtil::error("XmlRpcServer::acceptConnection: Could not set socket to non-blocking input mode (%s).", XmlRpcSocket::getErrorMsg().c_str());
158 }
159 else // Notify the dispatcher to listen for input on this source when we are in work()
160 {
161 XmlRpcUtil::log(2, "XmlRpcServer::acceptConnection: creating a connection");
163 }
164}
165
166
167// Create a new connection object for processing requests from a specific client.
170{
171 // Specify that the connection object be deleted when it is closed
172 return new XmlRpcServerConnection(s, this, true);
173}
174
175
176void
181
182
183// Stop processing client requests
184void
186{
187 _disp.exit();
188}
189
190
191// Close the server socket file descriptor and stop monitoring connections
192void
194{
195 // This closes and destroys all connections as well as closing this socket
196 _disp.clear();
197}
198
199
200// Introspection support
201static const std::string LIST_METHODS("system.listMethods");
202static const std::string METHOD_HELP("system.methodHelp");
203static const std::string MULTICALL("system.multicall");
204
205
206// List all methods available on a server
208{
209public:
211
212 void execute(XmlRpcValue& params, XmlRpcValue& result)
213 {
214 _server->listMethods(result);
215 }
216
217 std::string help() { return std::string("List all methods available on a server as an array of strings"); }
218};
219
220
221// Retrieve the help string for a named method
223{
224public:
226
227 void execute(XmlRpcValue& params, XmlRpcValue& result)
228 {
229 if (params[0].getType() != XmlRpcValue::TypeString)
230 throw XmlRpcException(METHOD_HELP + ": Invalid argument type");
231
232 XmlRpcServerMethod* m = _server->findMethod(params[0]);
233 if ( ! m)
234 throw XmlRpcException(METHOD_HELP + ": Unknown method name");
235
236 result = m->help();
237 }
238
239 std::string help() { return std::string("Retrieve the help string for a named method"); }
240};
241
242
243// Specify whether introspection is enabled or not. Default is enabled.
244void
246{
247 if (_introspectionEnabled == enabled)
248 return;
249
250 _introspectionEnabled = enabled;
251
252 if (enabled)
253 {
254 if ( ! _listMethods)
255 {
256 _listMethods = new ListMethods(this);
257 _methodHelp = new MethodHelp(this);
258 } else {
261 }
262 }
263 else
264 {
265 removeMethod(LIST_METHODS);
266 removeMethod(METHOD_HELP);
267 }
268}
269
270
271void
273{
274 int i = 0;
275 result.setSize(_methods.size()+1);
276 for (MethodMap::iterator it=_methods.begin(); it != _methods.end(); ++it)
277 result[i++] = it->first;
278
279 // Multicall support is built into XmlRpcServerConnection
280 result[i] = MULTICALL;
281}
282
283
284
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.
void removeSource(XmlRpcSource *source)
@ ReadableEvent
data available to read
void work(double msTime)
void exit()
Exit from work routine.
void clear()
Clear all sources from the monitored sources list. Sources are closed.
void addSource(XmlRpcSource *source, unsigned eventMask)
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.
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()
Close the owned fd. If deleteOnClose was specified at construction, the object is deleted.
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.