00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "llagent.h"
00035 #include "lleventpoll.h"
00036
00037 #include "llhttpclient.h"
00038 #include "llsdserialize.h"
00039 #include "llviewerregion.h"
00040 #include "message.h"
00041
00042 namespace
00043 {
00044 class LLEventPollResponder : public LLHTTPClient::Responder
00045 {
00046 public:
00047
00048 static LLHTTPClient::ResponderPtr start(const std::string& pollURL, const LLHost& sender);
00049 void stop();
00050
00051 private:
00052 LLEventPollResponder(const std::string& pollURL, const LLHost& sender);
00053 ~LLEventPollResponder();
00054
00055 void makeRequest();
00056 void handleMessage(const LLSD& content);
00057 virtual void error(U32 status, const std::string& reason);
00058 virtual void result(const LLSD& content);
00059
00060 private:
00061
00062 bool mDone;
00063
00064 std::string mPollURL;
00065 std::string mSender;
00066
00067 LLSD mAcknowledge;
00068
00069
00070 static int sCount;
00071 int mCount;
00072 };
00073
00074
00075 LLHTTPClient::ResponderPtr LLEventPollResponder::start(
00076 const std::string& pollURL, const LLHost& sender)
00077 {
00078 LLHTTPClient::ResponderPtr result = new LLEventPollResponder(pollURL, sender);
00079 llinfos << "LLEventPollResponder::start <" << sCount << "> "
00080 << pollURL << llendl;
00081 return result;
00082 }
00083
00084 void LLEventPollResponder::stop()
00085 {
00086 llinfos << "LLEventPollResponder::stop <" << mCount << "> "
00087 << mPollURL << llendl;
00088
00089 mDone = true;
00090 }
00091
00092 int LLEventPollResponder::sCount = 0;
00093
00094 LLEventPollResponder::LLEventPollResponder(const std::string& pollURL, const LLHost& sender)
00095 : mDone(false),
00096 mPollURL(pollURL),
00097 mCount(++sCount)
00098 {
00099
00100 LLViewerRegion *regionp = gAgent.getRegion();
00101 if (!regionp)
00102 {
00103 llerrs << "LLEventPoll initialized before region is added." << llendl;
00104 }
00105 mSender = sender.getIPandPort();
00106 llinfos << "LLEventPoll initialized with sender " << mSender << llendl;
00107 makeRequest();
00108 }
00109
00110 LLEventPollResponder::~LLEventPollResponder()
00111 {
00112 stop();
00113 lldebugs << "LLEventPollResponder::~Impl <" << mCount << "> "
00114 << mPollURL << llendl;
00115 }
00116
00117 void LLEventPollResponder::makeRequest()
00118 {
00119 LLSD request;
00120 request["ack"] = mAcknowledge;
00121 request["done"] = mDone;
00122
00123 lldebugs << "LLEventPollResponder::makeRequest <" << mCount << "> ack = "
00124 << LLSDXMLStreamer(mAcknowledge) << llendl;
00125 LLHTTPClient::post(mPollURL, request, this);
00126 }
00127
00128 void LLEventPollResponder::handleMessage(const LLSD& content)
00129 {
00130 std::string msg_name = content["message"];
00131 LLSD message;
00132 message["sender"] = mSender;
00133 message["body"] = content["body"];
00134 LLMessageSystem::dispatch(msg_name, message);
00135 }
00136
00137
00138 void LLEventPollResponder::error(U32 status, const std::string& reason)
00139 {
00140 if (mDone) return;
00141
00142 if(status != 499)
00143 {
00144 llwarns << "LLEventPollResponder::error: <" << mCount << "> got "
00145 << status << ": " << reason
00146 << (mDone ? " -- done" : "") << llendl;
00147 stop();
00148 return;
00149 }
00150
00151 makeRequest();
00152 }
00153
00154
00155 void LLEventPollResponder::result(const LLSD& content)
00156 {
00157 lldebugs << "LLEventPollResponder::result <" << mCount << ">"
00158 << (mDone ? " -- done" : "") << llendl;
00159
00160 if (mDone) return;
00161
00162 if (!content.get("events") ||
00163 !content.get("id"))
00164 {
00165 llwarns << "received event poll with no events or id key" << llendl;
00166 return;
00167 }
00168
00169 mAcknowledge = content["id"];
00170 LLSD events = content["events"];
00171
00172 if(mAcknowledge.isUndefined())
00173 {
00174 llwarns << "LLEventPollResponder: id undefined" << llendl;
00175 }
00176
00177
00178 lldebugs << "LLEventPollResponder::completed <" << mCount << "> " << events.size() << "events (id "
00179 << LLSDXMLStreamer(mAcknowledge) << ")" << llendl;
00180
00181 LLSD::array_const_iterator i = events.beginArray();
00182 LLSD::array_const_iterator end = events.endArray();
00183 for (; i != end; ++i)
00184 {
00185 if (i->has("message"))
00186 {
00187 handleMessage(*i);
00188 }
00189 }
00190
00191 makeRequest();
00192 }
00193 }
00194
00195 LLEventPoll::LLEventPoll(const std::string& pollURL, const LLHost& sender)
00196 : mImpl(LLEventPollResponder::start(pollURL, sender))
00197 { }
00198
00199 LLEventPoll::~LLEventPoll()
00200 {
00201 }