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

游戏引擎

开发平台:

C++ Builder

  1. /**
  2.  * @file   llsdmessage.h
  3.  * @author Nat Goodspeed
  4.  * @date   2008-10-30
  5.  * @brief  API intended to unify sending capability, UDP and TCP messages:
  6.  *         https://wiki.lindenlab.com/wiki/Viewer:Messaging/Messaging_Notes
  7.  * 
  8.  * $LicenseInfo:firstyear=2008&license=viewergpl$
  9.  * 
  10.  * Copyright (c) 2008-2010, Linden Research, Inc.
  11.  * 
  12.  * Second Life Viewer Source Code
  13.  * The source code in this file ("Source Code") is provided by Linden Lab
  14.  * to you under the terms of the GNU General Public License, version 2.0
  15.  * ("GPL"), unless you have obtained a separate licensing agreement
  16.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  17.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  18.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  19.  * 
  20.  * There are special exceptions to the terms and conditions of the GPL as
  21.  * it is applied to this Source Code. View the full text of the exception
  22.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  23.  * online at
  24.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  25.  * 
  26.  * By copying, modifying or distributing this software, you acknowledge
  27.  * that you have read and understood your obligations described above,
  28.  * and agree to abide by those obligations.
  29.  * 
  30.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  31.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  32.  * COMPLETENESS OR PERFORMANCE.
  33.  * $/LicenseInfo$
  34.  */
  35. #if ! defined(LL_LLSDMESSAGE_H)
  36. #define LL_LLSDMESSAGE_H
  37. #include "llerror.h"                // LOG_CLASS()
  38. #include "llevents.h"               // LLEventPumps
  39. #include "llhttpclient.h"
  40. #include <string>
  41. #include <stdexcept>
  42. class LLSD;
  43. /**
  44.  * Class managing the messaging API described in
  45.  * https://wiki.lindenlab.com/wiki/Viewer:Messaging/Messaging_Notes
  46.  */
  47. class LLSDMessage
  48. {
  49.     LOG_CLASS(LLSDMessage);
  50. public:
  51.     LLSDMessage();
  52.     /// Exception if you specify arguments badly
  53.     struct ArgError: public std::runtime_error
  54.     {
  55.         ArgError(const std::string& what):
  56.             std::runtime_error(std::string("ArgError: ") + what) {}
  57.     };
  58.     /**
  59.      * The response idiom used by LLSDMessage -- LLEventPump names on which to
  60.      * post reply or error -- is designed for the case in which your
  61.      * reply/error handlers are methods on the same class as the method
  62.      * sending the message. Any state available to the sending method that
  63.      * must be visible to the reply/error methods can conveniently be stored
  64.      * on that class itself, if it's not already.
  65.      *
  66.      * The LLHTTPClient::Responder idiom requires a separate instance of a
  67.      * separate class so that it can dispatch to the code of interest by
  68.      * calling canonical virtual methods. Interesting state must be copied
  69.      * into that new object. 
  70.      *
  71.      * With some trepidation, because existing response code is packaged in
  72.      * LLHTTPClient::Responder subclasses, we provide this adapter class
  73.      * <i>for transitional purposes only.</i> Instantiate a new heap
  74.      * ResponderAdapter with your new LLHTTPClient::ResponderPtr. Pass
  75.      * ResponderAdapter::getReplyName() and/or getErrorName() in your
  76.      * LLSDMessage (or LLViewerRegion::getCapAPI()) request event. The
  77.      * ResponderAdapter will call the appropriate Responder method, then
  78.      * @c delete itself.
  79.      */
  80.     class ResponderAdapter
  81.     {
  82.     public:
  83.         /**
  84.          * Bind the new LLHTTPClient::Responder subclass instance.
  85.          *
  86.          * Passing the constructor a name other than the default is only
  87.          * interesting if you suspect some usage will lead to an exception or
  88.          * log message.
  89.          */
  90.         ResponderAdapter(LLHTTPClient::ResponderPtr responder,
  91.                          const std::string& name="ResponderAdapter");
  92.         /// EventPump name on which LLSDMessage should post reply event
  93.         std::string getReplyName() const { return mReplyPump.getName(); }
  94.         /// EventPump name on which LLSDMessage should post error event
  95.         std::string getErrorName() const { return mErrorPump.getName(); }
  96.     private:
  97.         // We have two different LLEventStreams, though we route them both to
  98.         // the same listener, so that we can bind an extra flag identifying
  99.         // which case (reply or error) reached that listener.
  100.         bool listener(const LLSD&, bool success);
  101.         LLHTTPClient::ResponderPtr mResponder;
  102.         LLEventStream mReplyPump, mErrorPump;
  103.     };
  104.     /**
  105.      * Force our implementation file to be linked with caller. The .cpp file
  106.      * contains a static instance of this class, which must be linked into the
  107.      * executable to support the canonical listener. But since the primary
  108.      * interface to that static instance is via a named LLEventPump rather
  109.      * than by direct reference, the linker doesn't necessarily perceive the
  110.      * necessity to bring in the translation unit. Referencing this dummy
  111.      * method forces the issue.
  112.      */
  113.     static void link();
  114. private:
  115.     friend class LLCapabilityListener;
  116.     /// Responder used for internal purposes by LLSDMessage and
  117.     /// LLCapabilityListener. Others should use higher-level APIs.
  118.     class EventResponder: public LLHTTPClient::Responder
  119.     {
  120.     public:
  121.         /**
  122.          * LLHTTPClient::Responder that dispatches via named LLEventPump instances.
  123.          * We bind LLEventPumps, even though it's an LLSingleton, for testability.
  124.          * We bind the string names of the desired LLEventPump instances rather
  125.          * than actually obtain()ing them so we only obtain() the one we're going
  126.          * to use. If the caller doesn't bother to listen() on it, the other pump
  127.          * may never materialize at all.
  128.          * @a target and @a message are only to clarify error processing.
  129.          * For a capability message, @a target should be the region description,
  130.          * @a message should be the capability name.
  131.          * For a service with a visible URL, pass the URL as @a target and the HTTP verb
  132.          * (e.g. "POST") as @a message.
  133.          */
  134.         EventResponder(LLEventPumps& pumps,
  135.                        const LLSD& request,
  136.                        const std::string& target, const std::string& message,
  137.                        const std::string& replyPump, const std::string& errorPump):
  138.             mPumps(pumps),
  139.             mReqID(request),
  140.             mTarget(target),
  141.             mMessage(message),
  142.             mReplyPump(replyPump),
  143.             mErrorPump(errorPump)
  144.         {}
  145.     
  146.         virtual void result(const LLSD& data);
  147.         virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
  148.     
  149.     private:
  150.         LLEventPumps& mPumps;
  151.         LLReqID mReqID;
  152.         const std::string mTarget, mMessage, mReplyPump, mErrorPump;
  153.     };
  154. private:
  155.     bool httpListener(const LLSD&);
  156.     LLEventStream mEventPump;
  157. };
  158. #endif /* ! defined(LL_LLSDMESSAGE_H) */