diff options
Diffstat (limited to 'OpenSim/Region/Environment/Modules')
-rw-r--r-- | OpenSim/Region/Environment/Modules/Framework/EventQueueGetModule.cs | 117 |
1 files changed, 105 insertions, 12 deletions
diff --git a/OpenSim/Region/Environment/Modules/Framework/EventQueueGetModule.cs b/OpenSim/Region/Environment/Modules/Framework/EventQueueGetModule.cs index c11a4db..1726ea2 100644 --- a/OpenSim/Region/Environment/Modules/Framework/EventQueueGetModule.cs +++ b/OpenSim/Region/Environment/Modules/Framework/EventQueueGetModule.cs | |||
@@ -68,6 +68,8 @@ namespace OpenSim.Region.Environment.Modules.Framework | |||
68 | private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>(); | 68 | private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>(); |
69 | 69 | ||
70 | private Dictionary<UUID, BlockingLLSDQueue> queues = new Dictionary<UUID, BlockingLLSDQueue>(); | 70 | private Dictionary<UUID, BlockingLLSDQueue> queues = new Dictionary<UUID, BlockingLLSDQueue>(); |
71 | private Dictionary<UUID, UUID> m_QueueUUIDAvatarMapping = new Dictionary<UUID, UUID>(); | ||
72 | private Dictionary<UUID, UUID> m_AvatarQueueUUIDMapping = new Dictionary<UUID, UUID>(); | ||
71 | 73 | ||
72 | 74 | ||
73 | #region IRegionModule methods | 75 | #region IRegionModule methods |
@@ -85,6 +87,10 @@ namespace OpenSim.Region.Environment.Modules.Framework | |||
85 | { | 87 | { |
86 | m_scene = scene; | 88 | m_scene = scene; |
87 | scene.RegisterModuleInterface<IEventQueue>(this); | 89 | scene.RegisterModuleInterface<IEventQueue>(this); |
90 | |||
91 | // Register fallback handler | ||
92 | // Why does EQG Fail on region crossings! | ||
93 | scene.AddLLSDHandler("/CAPS/EQG/", EventQueueFallBack); | ||
88 | 94 | ||
89 | scene.EventManager.OnNewClient += OnNewClient; | 95 | scene.EventManager.OnNewClient += OnNewClient; |
90 | scene.EventManager.OnClientClosed += ClientClosed; | 96 | scene.EventManager.OnClientClosed += ClientClosed; |
@@ -185,9 +191,39 @@ namespace OpenSim.Region.Environment.Modules.Framework | |||
185 | public void OnRegisterCaps(UUID agentID, Caps caps) | 191 | public void OnRegisterCaps(UUID agentID, Caps caps) |
186 | { | 192 | { |
187 | m_log.DebugFormat("[EVENTQUEUE] OnRegisterCaps: agentID {0} caps {1} region {2}", agentID, caps, m_scene.RegionInfo.RegionName); | 193 | m_log.DebugFormat("[EVENTQUEUE] OnRegisterCaps: agentID {0} caps {1} region {2}", agentID, caps, m_scene.RegionInfo.RegionName); |
188 | string capsBase = "/CAPS/"; | 194 | string capsBase = "/CAPS/EQG/"; |
195 | UUID EventQueueGetUUID = UUID.Zero; | ||
196 | |||
197 | lock (m_AvatarQueueUUIDMapping) | ||
198 | { | ||
199 | // Reuse open queues. The client does! | ||
200 | if (m_AvatarQueueUUIDMapping.ContainsKey(agentID)) | ||
201 | { | ||
202 | m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!"); | ||
203 | EventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID]; | ||
204 | } | ||
205 | else | ||
206 | { | ||
207 | EventQueueGetUUID = UUID.Random(); | ||
208 | m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!"); | ||
209 | } | ||
210 | } | ||
211 | |||
212 | lock (m_QueueUUIDAvatarMapping) | ||
213 | { | ||
214 | if (!m_QueueUUIDAvatarMapping.ContainsKey(EventQueueGetUUID)) | ||
215 | m_QueueUUIDAvatarMapping.Add(EventQueueGetUUID, agentID); | ||
216 | } | ||
217 | |||
218 | lock (m_AvatarQueueUUIDMapping) | ||
219 | { | ||
220 | if (!m_AvatarQueueUUIDMapping.ContainsKey(agentID)) | ||
221 | m_AvatarQueueUUIDMapping.Add(agentID, EventQueueGetUUID); | ||
222 | } | ||
223 | |||
224 | m_log.DebugFormat("[EVENTQUEUE]: CAPS URL: {0}", capsBase + EventQueueGetUUID.ToString() + "/"); | ||
189 | caps.RegisterHandler("EventQueueGet", | 225 | caps.RegisterHandler("EventQueueGet", |
190 | new RestHTTPHandler("POST", capsBase + UUID.Random().ToString(), | 226 | new RestHTTPHandler("POST", capsBase + EventQueueGetUUID.ToString(), |
191 | delegate(Hashtable m_dhttpMethod) | 227 | delegate(Hashtable m_dhttpMethod) |
192 | { | 228 | { |
193 | return ProcessQueue(m_dhttpMethod,agentID, caps); | 229 | return ProcessQueue(m_dhttpMethod,agentID, caps); |
@@ -235,15 +271,7 @@ namespace OpenSim.Region.Environment.Modules.Framework | |||
235 | return responsedata; | 271 | return responsedata; |
236 | } | 272 | } |
237 | 273 | ||
238 | if (thisID == -1) // close-request | 274 | |
239 | { | ||
240 | responsedata["int_response_code"] = 502; | ||
241 | responsedata["content_type"] = "text/plain"; | ||
242 | responsedata["keepalive"] = false; | ||
243 | responsedata["str_response_string"] = ""; | ||
244 | return responsedata; | ||
245 | } | ||
246 | |||
247 | LLSDArray array = new LLSDArray(); | 275 | LLSDArray array = new LLSDArray(); |
248 | if (element == null) // didn't have an event in 15s | 276 | if (element == null) // didn't have an event in 15s |
249 | { | 277 | { |
@@ -272,11 +300,76 @@ namespace OpenSim.Region.Environment.Modules.Framework | |||
272 | 300 | ||
273 | responsedata["int_response_code"] = 200; | 301 | responsedata["int_response_code"] = 200; |
274 | responsedata["content_type"] = "application/xml"; | 302 | responsedata["content_type"] = "application/xml"; |
275 | responsedata["keepalive"] = true; | 303 | responsedata["keepalive"] = false; |
276 | responsedata["str_response_string"] = LLSDParser.SerializeXmlString(events); | 304 | responsedata["str_response_string"] = LLSDParser.SerializeXmlString(events); |
277 | m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", agentID, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]); | 305 | m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", agentID, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]); |
278 | 306 | ||
279 | return responsedata; | 307 | return responsedata; |
280 | } | 308 | } |
309 | public LLSD EventQueueFallBack(string path, LLSD request, string endpoint) | ||
310 | { | ||
311 | // This is a fallback element to keep the client from loosing EventQueueGet | ||
312 | // Why does CAPS fail sometimes!? | ||
313 | m_log.Warn("[EVENTQUEUE]: In the Fallback handler! We lost the Queue in the rest handler!"); | ||
314 | string capuuid = path.Replace("/CAPS/EQG/",""); | ||
315 | capuuid = capuuid.Substring(0, capuuid.Length - 1); | ||
316 | |||
317 | UUID AvatarID = UUID.Zero; | ||
318 | UUID capUUID = UUID.Zero; | ||
319 | if (UUID.TryParse(capuuid, out capUUID)) | ||
320 | { | ||
321 | |||
322 | lock (m_QueueUUIDAvatarMapping) | ||
323 | { | ||
324 | if (m_QueueUUIDAvatarMapping.ContainsKey(capUUID)) | ||
325 | { | ||
326 | AvatarID = m_QueueUUIDAvatarMapping[capUUID]; | ||
327 | } | ||
328 | } | ||
329 | if (AvatarID != UUID.Zero) | ||
330 | { | ||
331 | int thisID = 0; | ||
332 | lock (m_ids) | ||
333 | thisID = m_ids[AvatarID]; | ||
334 | |||
335 | BlockingLLSDQueue queue = GetQueue(AvatarID); | ||
336 | LLSDArray array = new LLSDArray(); | ||
337 | LLSD element = queue.Dequeue(15000); // 15s timeout | ||
338 | if (element == null) | ||
339 | { | ||
340 | |||
341 | array.Add(EventQueueHelper.KeepAliveEvent()); | ||
342 | } | ||
343 | else | ||
344 | { | ||
345 | array.Add(element); | ||
346 | while (queue.Count() > 0) | ||
347 | { | ||
348 | array.Add(queue.Dequeue(1)); | ||
349 | thisID++; | ||
350 | } | ||
351 | } | ||
352 | LLSDMap events = new LLSDMap(); | ||
353 | events.Add("events", array); | ||
354 | |||
355 | events.Add("id", new LLSDInteger(thisID)); | ||
356 | |||
357 | lock (m_ids) | ||
358 | { | ||
359 | m_ids[AvatarID] = thisID + 1; | ||
360 | } | ||
361 | |||
362 | return events; | ||
363 | } | ||
364 | else | ||
365 | { | ||
366 | return new LLSD(); | ||
367 | } | ||
368 | } | ||
369 | else | ||
370 | { | ||
371 | return new LLSD(); | ||
372 | } | ||
373 | } | ||
281 | } | 374 | } |
282 | } | 375 | } |