llsdrpcserver.h
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:10k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llsdrpcserver.h
  3.  * @author Phoenix
  4.  * @date 2005-10-11
  5.  * @brief Declaration of the structured data remote procedure call server.
  6.  *
  7.  * $LicenseInfo:firstyear=2005&license=viewergpl$
  8.  * 
  9.  * Copyright (c) 2005-2010, Linden Research, Inc.
  10.  * 
  11.  * Second Life Viewer Source Code
  12.  * The source code in this file ("Source Code") is provided by Linden Lab
  13.  * to you under the terms of the GNU General Public License, version 2.0
  14.  * ("GPL"), unless you have obtained a separate licensing agreement
  15.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  16.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  17.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  18.  * 
  19.  * There are special exceptions to the terms and conditions of the GPL as
  20.  * it is applied to this Source Code. View the full text of the exception
  21.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  22.  * online at
  23.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  24.  * 
  25.  * By copying, modifying or distributing this software, you acknowledge
  26.  * that you have read and understood your obligations described above,
  27.  * and agree to abide by those obligations.
  28.  * 
  29.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  30.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  31.  * COMPLETENESS OR PERFORMANCE.
  32.  * $/LicenseInfo$
  33.  */
  34. #ifndef LL_LLSDRPCSERVER_H
  35. #define LL_LLSDRPCSERVER_H
  36. /** 
  37.  * I've set this up to be pretty easy to use when you want to make a
  38.  * structured data rpc server which responds to methods by
  39.  * name. Derive a class from the LLSDRPCServer, and during
  40.  * construction (or initialization if you have the luxury) map method
  41.  * names to pointers to member functions. This will look a lot like:
  42.  *
  43.  * <code>
  44.  *  class LLMessageAgents : public LLSDRPCServer {<br>
  45.  *  public:<br>
  46.  *    typedef LLSDRPCServer<LLUsher> mem_fn_t;<br>
  47.  *    LLMessageAgents() {<br>
  48.  *      mMethods["message"] = new mem_fn_t(this, &LLMessageAgents::rpc_IM);<br>
  49.  *      mMethods["alert"] = new mem_fn_t(this, &LLMessageAgents::rpc_Alrt);<br>
  50.  *    }<br>
  51.  *  protected:<br>
  52.  *    rpc_IM(const LLSD& params,
  53.  * const LLChannelDescriptors& channels,
  54.  * LLBufferArray* data)
  55.  * {...}<br>
  56.  *    rpc_Alert(const LLSD& params,
  57.  * const LLChannelDescriptors& channels,
  58.  * LLBufferArray* data)
  59.  * {...}<br>
  60.  *  };<br>
  61.  * </code>
  62.  *
  63.  * The params are an array where each element in the array is a single
  64.  * parameter in the call.
  65.  *
  66.  * It is up to you to pack a valid serialized llsd response into the
  67.  * data object passed into the method, but you can use the helper
  68.  * methods below to help.
  69.  */
  70. #include <map>
  71. #include "lliopipe.h"
  72. #include "lliohttpserver.h"
  73. #include "llfiltersd2xmlrpc.h"
  74. class LLSD;
  75. /** 
  76.  * @brief Enumeration for specifying server method call status. This
  77.  * enumeration controls how the server class will manage the pump
  78.  * process/callback mechanism.
  79.  */
  80. enum ESDRPCSStatus
  81. {
  82.   // The call went ok, but the response is not yet ready. The
  83.   // method will arrange for the clearLock() call to be made at
  84.   // a later date, after which, once the chain is being pumped
  85. // again, deferredResponse() will be called to gather the result
  86.   ESDRPCS_DEFERRED,
  87. // The LLSDRPCServer would like to handle the method on the
  88. // callback queue of the pump.
  89. ESDRPCS_CALLBACK,
  90. // The method call finished and generated output.
  91. ESDRPCS_DONE,
  92. // Method failed for some unspecified reason - you should avoid
  93. // this. A generic fault will be sent to the output.
  94. ESDRPCS_ERROR,
  95. ESDRPCS_COUNT,
  96. };
  97. /** 
  98.  * @class LLSDRPCMethodCallBase
  99.  * @brief Base class for calling a member function in an sd rpcserver
  100.  * implementation.
  101.  */
  102. class LLSDRPCMethodCallBase
  103. {
  104. public:
  105. LLSDRPCMethodCallBase() {}
  106. virtual ~LLSDRPCMethodCallBase() {}
  107. virtual ESDRPCSStatus call(
  108. const LLSD& params,
  109. const LLChannelDescriptors& channels,
  110. LLBufferArray* response) = 0;
  111. protected:
  112. };
  113. /** 
  114.  * @class LLSDRPCMethodCall
  115.  * @brief Class which implements member function calls.
  116.  */
  117. template<class Server>
  118. class LLSDRPCMethodCall : public LLSDRPCMethodCallBase
  119. {
  120. public:
  121. typedef ESDRPCSStatus (Server::*mem_fn)(
  122. const LLSD& params,
  123. const LLChannelDescriptors& channels,
  124. LLBufferArray* data);
  125. LLSDRPCMethodCall(Server* s, mem_fn fn) :
  126. mServer(s),
  127. mMemFn(fn)
  128. {
  129. }
  130. virtual ~LLSDRPCMethodCall() {}
  131. virtual ESDRPCSStatus call(
  132. const LLSD& params,
  133. const LLChannelDescriptors& channels,
  134. LLBufferArray* data)
  135. {
  136. return (*mServer.*mMemFn)(params, channels, data);
  137. }
  138. protected:
  139. Server* mServer;
  140. mem_fn mMemFn;
  141. //bool (Server::*mMemFn)(const LLSD& params, LLBufferArray& data);
  142. };
  143. /** 
  144.  * @class LLSDRPCServer
  145.  * @brief Basic implementation of a structure data rpc server
  146.  *
  147.  * The rpc server is also designed to appropriately straddle the pump
  148.  * <code>process()</code> and <code>callback()</code> to specify which
  149.  * thread you want to work on when handling a method call. The
  150.  * <code>mMethods</code> methods are called from
  151.  * <code>process()</code>, while the <code>mCallbackMethods</code> are
  152.  * called when a pump is in a <code>callback()</code> cycle.
  153.  */
  154. class LLSDRPCServer : public LLIOPipe
  155. {
  156. public:
  157. LLSDRPCServer();
  158. virtual ~LLSDRPCServer();
  159. /**
  160.  * enumeration for generic fault codes
  161.  */
  162. enum
  163. {
  164. FAULT_BAD_REQUEST = 2000,
  165. FAULT_NO_RESPONSE = 2001,
  166. };
  167. /** 
  168.  * @brief Call this method to return an rpc fault.
  169.  *
  170.  * @param channel The channel for output on the data buffer
  171.  * @param data buffer which will recieve the final output 
  172.  * @param code The fault code 
  173.  * @param msg The fault message 
  174.  */
  175. static void buildFault(
  176. const LLChannelDescriptors& channels,
  177. LLBufferArray* data,
  178. S32 code,
  179. const std::string& msg);
  180. /** 
  181.  * @brief Call this method to build an rpc response.
  182.  *
  183.  * @param channel The channel for output on the data buffer
  184.  * @param data buffer which will recieve the final output 
  185.  * @param response The return value from the method call
  186.  */
  187. static void buildResponse(
  188. const LLChannelDescriptors& channels,
  189. LLBufferArray* data,
  190. const LLSD& response);
  191. protected:
  192. /* @name LLIOPipe virtual implementations
  193.  */
  194. //@{
  195. /** 
  196.  * @brief Process the data in buffer
  197.  */
  198. virtual EStatus process_impl(
  199. const LLChannelDescriptors& channels,
  200. buffer_ptr_t& buffer,
  201. bool& eos,
  202. LLSD& context,
  203. LLPumpIO* pump);
  204. //@}
  205. protected:
  206. /** 
  207.  * @brief Enumeration to track the state of the rpc server instance
  208.  */
  209. enum EState
  210. {
  211. STATE_NONE,
  212. STATE_CALLBACK,
  213. STATE_DEFERRED,
  214. STATE_DONE
  215. };
  216. /** 
  217.  * @brief This method is called when an http post comes in.
  218.  *
  219.  * The default behavior is to look at the method name, look up the
  220.  * method in the method table, and call it. If the method is not
  221.  * found, this function will build a fault response.  You can
  222.  * implement your own version of this function if you want to hard
  223.  * wire some behavior or optimize things a bit.
  224.  * @param method The method name being called
  225.  * @param params The parameters
  226.  * @param channel The channel for output on the data buffer
  227.  * @param data The http data
  228.  * @return Returns the status of the method call, done/deferred/etc
  229.  */
  230. virtual ESDRPCSStatus callMethod(
  231. const std::string& method,
  232. const LLSD& params,
  233. const LLChannelDescriptors& channels,
  234. LLBufferArray* data);
  235. /** 
  236.  * @brief This method is called when a pump callback is processed.
  237.  *
  238.  * The default behavior is to look at the method name, look up the
  239.  * method in the callback method table, and call it. If the method
  240.  * is not found, this function will build a fault response.  You
  241.  * can implement your own version of this function if you want to
  242.  * hard wire some behavior or optimize things a bit.
  243.  * @param method The method name being called
  244.  * @param params The parameters
  245.  * @param channel The channel for output on the data buffer
  246.  * @param data The http data
  247.  * @return Returns the status of the method call, done/deferred/etc
  248.  */
  249. virtual ESDRPCSStatus callbackMethod(
  250. const std::string& method,
  251. const LLSD& params,
  252. const LLChannelDescriptors& channels,
  253. LLBufferArray* data);
  254. /**
  255.  * @brief Called after a deferred service is unlocked
  256.  *
  257.  * If a method returns ESDRPCS_DEFERRED, then the service chain
  258.  * will be locked and not processed until some other system calls
  259.  * clearLock() on the service instance again.  At that point,
  260.  * once the pump starts processing the chain again, this method
  261.  * will be called so the service can output the final result
  262.  * into the buffers.
  263.  */
  264. virtual ESDRPCSStatus deferredResponse(
  265. const LLChannelDescriptors& channels,
  266. LLBufferArray* data);
  267. // donovan put this public here 7/27/06
  268. public:
  269. /**
  270.  * @brief unlock a service that as ESDRPCS_DEFERRED
  271.  */
  272. void clearLock();
  273. protected:
  274. EState mState;
  275. LLSD mRequest;
  276. LLPumpIO* mPump;
  277. S32 mLock;
  278. typedef std::map<std::string, LLSDRPCMethodCallBase*> method_map_t;
  279. method_map_t mMethods;
  280. method_map_t mCallbackMethods;
  281. };
  282. /** 
  283.  * @name Helper Templates for making LLHTTPNodes
  284.  *
  285.  * These templates help in creating nodes for handing a service from
  286.  * either SDRPC or XMLRPC, given a single implementation of LLSDRPCServer.
  287.  *
  288.  * To use it:
  289.  * code
  290.  *  class LLUsefulServer : public LLSDRPCServer { ... }
  291.  *
  292.  *  LLHTTPNode& root = LLCreateHTTPWireServer(...);
  293.  *  root.addNode("llsdrpc/useful", new LLSDRPCNode<LLUsefulServer>);
  294.  *  root.addNode("xmlrpc/useful", new LLXMLRPCNode<LLUsefulServer>);
  295.  * endcode
  296.  */
  297. //@{
  298. template<class Server>
  299. class LLSDRPCServerFactory : public LLChainIOFactory
  300. {
  301. public:
  302. virtual bool build(LLPumpIO::chain_t& chain, LLSD context) const
  303. {
  304. lldebugs << "LLXMLSDRPCServerFactory::build" << llendl;
  305. chain.push_back(LLIOPipe::ptr_t(new Server));
  306. return true;
  307. }
  308. };
  309. template<class Server>
  310. class LLSDRPCNode : public LLHTTPNodeForFactory<
  311. LLSDRPCServerFactory<Server> >
  312. {
  313. };
  314. template<class Server>
  315. class LLXMLRPCServerFactory : public LLChainIOFactory
  316. {
  317. public:
  318. virtual bool build(LLPumpIO::chain_t& chain, LLSD context) const
  319. {
  320. lldebugs << "LLXMLSDRPCServerFactory::build" << llendl;
  321. chain.push_back(LLIOPipe::ptr_t(new LLFilterXMLRPCRequest2LLSD));
  322. chain.push_back(LLIOPipe::ptr_t(new Server));
  323. chain.push_back(LLIOPipe::ptr_t(new LLFilterSD2XMLRPCResponse));
  324. return true;
  325. }
  326. };
  327. template<class Server>
  328. class LLXMLRPCNode : public LLHTTPNodeForFactory<
  329.   LLXMLRPCServerFactory<Server> >
  330. {
  331. };
  332. //@}
  333. #endif // LL_LLSDRPCSERVER_H