29 using System.Collections;
30 using System.Collections.Generic;
32 using System.Reflection;
33 using System.Threading;
38 using OpenSim.Framework;
39 using OpenSim.Framework.Monitoring;
40 using OpenSim.Framework.Servers;
41 using OpenSim.Framework.Servers.HttpServer;
42 using OpenSim.Region.Framework.Interfaces;
43 using OpenSim.Region.Framework.Scenes;
81 [Extension(Path =
"/OpenSim/RegionModules", NodeName =
"RegionModule", Id =
"XMLRPCModule")]
84 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
86 private string m_name =
"XMLRPCModule";
89 private Dictionary<UUID, RPCChannelInfo> m_openChannels;
90 private Dictionary<UUID, SendRemoteDataRequest> m_pendingSRDResponses;
91 private int m_remoteDataPort = 0;
94 get {
return m_remoteDataPort; }
97 private Dictionary<UUID, RPCRequestInfo> m_rpcPending;
98 private Dictionary<UUID, RPCRequestInfo> m_rpcPendingResponses;
99 private List<Scene> m_scenes =
new List<Scene>();
100 private int RemoteReplyScriptTimeout = 9000;
101 private int RemoteReplyScriptWait = 300;
102 private object XMLRPCListLock =
new object();
104 #region ISharedRegionModule Members
111 m_openChannels =
new Dictionary<UUID, RPCChannelInfo>();
112 m_rpcPending =
new Dictionary<UUID, RPCRequestInfo>();
113 m_rpcPendingResponses =
new Dictionary<UUID, RPCRequestInfo>();
114 m_pendingSRDResponses =
new Dictionary<UUID, SendRemoteDataRequest>();
115 if (config.Configs[
"XMLRPC"] != null)
119 m_remoteDataPort = config.Configs[
"XMLRPC"].GetInt(
"XmlRpcPort", m_remoteDataPort);
138 httpServer.AddXmlRPCHandler(
"llRemoteData", XmlRpcRemoteData);
147 if (!m_scenes.Contains(scene))
151 scene.RegisterModuleInterface<
IXMLRPC>(
this);
164 if (m_scenes.Contains(scene))
166 scene.UnregisterModuleInterface<
IXMLRPC>(
this);
167 m_scenes.Remove(scene);
177 get {
return m_name; }
180 public Type ReplaceableInterface
187 #region IXMLRPC Members
191 return (m_remoteDataPort > 0);
214 UUID newChannel = UUID.Zero;
217 if (null == m_openChannels)
219 m_log.Warn(
"[XML RPC MODULE]: Attempt to open channel before initialization is complete");
229 newChannel = ci.GetChannelID();
234 if (newChannel ==
UUID.Zero)
236 newChannel = (channelID == UUID.Zero) ?
UUID.Random() : channelID;
238 lock (XMLRPCListLock)
240 m_openChannels.Add(newChannel, rpcChanInfo);
251 if (m_openChannels != null)
253 ArrayList tmp =
new ArrayList();
255 lock (XMLRPCListLock)
265 IEnumerator tmpEnumerator = tmp.GetEnumerator();
266 while (tmpEnumerator.MoveNext())
267 m_openChannels.Remove((
UUID) tmpEnumerator.Current);
279 public void RemoteDataReply(
string channel,
string message_id,
string sdata,
int idata)
281 UUID message_key =
new UUID(message_id);
282 UUID channel_key =
new UUID(channel);
286 if (message_key ==
UUID.Zero)
288 foreach (
RPCRequestInfo oneRpcInfo
in m_rpcPendingResponses.Values)
290 rpcInfo = oneRpcInfo;
294 m_rpcPendingResponses.TryGetValue(message_key, out rpcInfo);
299 rpcInfo.SetStrRetval(sdata);
300 rpcInfo.SetIntRetval(idata);
301 rpcInfo.SetProcessed(
true);
302 m_rpcPendingResponses.Remove(message_key);
306 m_log.Warn(
"[XML RPC MODULE]: Channel or message_id not found");
319 if (m_openChannels.ContainsKey(channelKey))
320 m_openChannels.Remove(channelKey);
326 lock (XMLRPCListLock)
328 if (m_rpcPending != null)
329 return (m_rpcPending.Count > 0);
337 if (m_rpcPending != null)
339 lock (XMLRPCListLock)
341 foreach (
UUID luid
in m_rpcPending.Keys)
345 if (m_rpcPending.TryGetValue(luid, out tmpReq))
347 if (!tmpReq.IsProcessed())
return tmpReq;
357 lock (XMLRPCListLock)
360 if (m_rpcPending.TryGetValue(
id, out tmp))
362 m_rpcPending.Remove(id);
363 m_rpcPendingResponses.Add(id, tmp);
367 m_log.Error(
"[XML RPC MODULE]: UNABLE TO REMOVE COMPLETED REQUEST");
372 public UUID SendRemoteData(uint localID, UUID itemID,
string channel,
string dest,
int idata,
string sdata)
375 localID, itemID, channel, dest, idata, sdata
377 m_pendingSRDResponses.Add(req.GetReqID(), req);
384 if (m_pendingSRDResponses != null)
386 lock (XMLRPCListLock)
388 foreach (
UUID luid
in m_pendingSRDResponses.Keys)
392 if (m_pendingSRDResponses.TryGetValue(luid, out tmpReq))
405 lock (XMLRPCListLock)
408 if (m_pendingSRDResponses.TryGetValue(
id, out tmpReq))
410 m_pendingSRDResponses.Remove(id);
417 if (m_pendingSRDResponses != null)
419 lock (XMLRPCListLock)
423 if (li.
ItemID.Equals(itemID))
424 m_pendingSRDResponses.Remove(li.
GetReqID());
434 XmlRpcResponse response =
new XmlRpcResponse();
436 Hashtable requestData = (Hashtable) request.Params[0];
437 bool GoodXML = (requestData.Contains(
"Channel") && requestData.Contains(
"IntValue") &&
438 requestData.Contains(
"StringValue"));
442 UUID channel =
new UUID((
string) requestData[
"Channel"]);
444 if (m_openChannels.TryGetValue(channel, out rpcChanInfo))
446 string intVal = Convert.ToInt32(requestData[
"IntValue"]).ToString();
447 string strVal = (string) requestData[
"StringValue"];
451 lock (XMLRPCListLock)
454 new RPCRequestInfo(rpcChanInfo.GetLocalID(), rpcChanInfo.GetItemID(), channel, strVal,
456 m_rpcPending.Add(rpcInfo.GetMessageID(), rpcInfo);
461 while (!rpcInfo.
IsProcessed() && (timeoutCtr < RemoteReplyScriptTimeout))
463 Thread.Sleep(RemoteReplyScriptWait);
464 timeoutCtr += RemoteReplyScriptWait;
468 Hashtable param =
new Hashtable();
469 param[
"StringValue"] = rpcInfo.GetStrRetval();
470 param[
"IntValue"] = rpcInfo.GetIntRetval();
472 ArrayList parameters =
new ArrayList();
473 parameters.Add(param);
475 response.Value = parameters;
480 response.SetFault(-1,
"Script timeout");
486 response.SetFault(-1,
"Invalid channel");
496 private UUID m_ChannelKey;
497 private string m_IntVal;
498 private UUID m_ItemID;
499 private uint m_localID;
500 private UUID m_MessageID;
501 private bool m_processed;
502 private int m_respInt;
503 private string m_respStr;
504 private string m_StrVal;
506 public RPCRequestInfo(uint localID, UUID itemID, UUID channelKey,
string strVal,
string intVal)
512 m_ChannelKey = channelKey;
513 m_MessageID = UUID.Random();
515 m_respStr = String.Empty;
531 m_processed = processed;
571 return int.Parse(m_IntVal);
582 private UUID m_ChannelKey;
583 private UUID m_itemID;
584 private uint m_localID;
588 m_ChannelKey = channelID;
611 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
615 private bool _finished;
618 get {
return _finished; }
619 set { _finished = value; }
621 private Thread httpThread;
623 private UUID _itemID;
626 get {
return _itemID; }
627 set { _itemID = value; }
629 private uint _localID;
632 get {
return _localID; }
633 set { _localID = value; }
638 get {
return _reqID; }
639 set { _reqID = value; }
648 this.Channel = channel;
655 ReqID = UUID.Random();
661 httpThread = WorkManager.StartThread(SendRequest,
"HttpRequestThread", ThreadPriority.BelowNormal,
true,
false);
671 Hashtable param =
new Hashtable();
676 string mName =
"llRemoteData";
677 if (!
string.IsNullOrEmpty(Channel))
678 if (!
UUID.TryParse(Channel, out parseUID))
681 param[
"Channel"] = Channel;
683 param[
"StringValue"] = Sdata;
684 param[
"IntValue"] = Convert.ToString(Idata);
686 ArrayList parameters =
new ArrayList();
687 parameters.Add(param);
688 XmlRpcRequest req =
new XmlRpcRequest(mName, parameters);
691 XmlRpcResponse resp = req.Send(DestURL, 30000);
695 if (resp.Value.GetType().Equals(typeof(Hashtable)))
697 respParms = (Hashtable) resp.Value;
701 ArrayList respData = (ArrayList) resp.Value;
702 respParms = (Hashtable) respData[0];
704 if (respParms != null)
706 if (respParms.Contains(
"StringValue"))
708 Sdata = (string) respParms[
"StringValue"];
710 if (respParms.Contains(
"IntValue"))
712 Idata = Convert.ToInt32(respParms[
"IntValue"]);
714 if (respParms.Contains(
"faultString"))
716 Sdata = (string) respParms[
"faultString"];
718 if (respParms.Contains(
"faultCode"))
720 Idata = Convert.ToInt32(respParms[
"faultCode"]);
728 m_log.Warn(
"[SendRemoteDataRequest]: Request failed");
729 m_log.Warn(we.StackTrace);
734 Watchdog.RemoveThread();
741 if (httpThread != null)
743 Watchdog.AbortThread(httpThread.ManagedThreadId);
UUID OpenXMLRPCChannel(uint localID, UUID itemID, UUID channelID)
void RemoteDataReply(string channel, string message_id, string sdata, int idata)
void RemoveCompletedRequest(UUID id)
void RegionLoaded(Scene scene)
This will be called once for every scene loaded. In a shared module this will be multiple times in on...
IXmlRpcRequestInfo GetNextCompletedRequest()
void SetStrRetval(string resp)
IServiceRequest GetNextCompletedSRDRequest()
void RemoveCompletedSRDRequest(UUID id)
RPCChannelInfo(uint localID, UUID itemID, UUID channelID)
Interface to OpenSimulator's built in HTTP server. Use this to register handlers (http, llsd, xmlrpc, etc.) for given URLs.
void PostInitialise()
This is called exactly once after all the shared region-modules have been instanciated and IRegionMod...
void SetProcessed(bool processed)
void AddRegion(Scene scene)
This is called whenever a Scene is added. For shared modules, this can happen several times...
void CloseXMLRPCChannel(UUID channelKey)
void Close()
This is the inverse to Initialise. After a Close(), this instance won't be usable anymore...
void RemoveRegion(Scene scene)
This is called whenever a Scene is removed. For shared modules, this can happen several times...
UUID SendRemoteData(uint localID, UUID itemID, string channel, string dest, int idata, string sdata)
XmlRpcResponse XmlRpcRemoteData(XmlRpcRequest request, IPEndPoint remoteClient)
Interactive OpenSim region server
void Initialise(IConfigSource config)
This is called to initialize the region module. For shared modules, this is called exactly once...
void CancelSRDRequests(UUID itemID)
void SetIntRetval(int resp)
void DeleteChannels(UUID itemID)
RPCRequestInfo(uint localID, UUID itemID, UUID channelKey, string strVal, string intVal)
SendRemoteDataRequest(uint localID, UUID itemID, string channel, string dest, int idata, string sdata)