aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs286
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs164
2 files changed, 342 insertions, 108 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs
new file mode 100644
index 0000000..7b8c418
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs
@@ -0,0 +1,286 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using log4net.Config;
31using Nini.Config;
32using NUnit.Framework;
33using OpenMetaverse;
34using OpenSim.Framework;
35using OpenSim.Framework.Servers;
36using OpenSim.Framework.Servers.HttpServer;
37using OpenSim.Region.CoreModules.Avatar.Chat;
38using OpenSim.Region.CoreModules.Framework;
39using OpenSim.Region.CoreModules.Framework.EntityTransfer;
40using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
41using OpenSim.Region.Framework.Scenes;
42using OpenSim.Services.Interfaces;
43using OpenSim.Tests.Common;
44using OpenSim.Tests.Common.Mock;
45
46namespace OpenSim.Region.CoreModules.Avatar.Chat.Tests
47{
48 [TestFixture]
49 public class ChatModuleTests : OpenSimTestCase
50 {
51 [TestFixtureSetUp]
52 public void FixtureInit()
53 {
54 // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
55 // We must do this here so that child agent positions are updated in a predictable manner.
56 Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest;
57 }
58
59 [TestFixtureTearDown]
60 public void TearDown()
61 {
62 // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
63 // threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression
64 // tests really shouldn't).
65 Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
66 }
67
68 private void SetupNeighbourRegions(TestScene sceneA, TestScene sceneB)
69 {
70 // XXX: HTTP server is not (and should not be) necessary for this test, though it's absence makes the
71 // CapabilitiesModule complain when it can't set up HTTP endpoints.
72 // BaseHttpServer httpServer = new BaseHttpServer(99999);
73 // MainServer.AddHttpServer(httpServer);
74 // MainServer.Instance = httpServer;
75
76 // We need entity transfer modules so that when sp2 logs into the east region, the region calls
77 // EntityTransferModuleto set up a child agent on the west region.
78 // XXX: However, this is not an entity transfer so is misleading.
79 EntityTransferModule etmA = new EntityTransferModule();
80 EntityTransferModule etmB = new EntityTransferModule();
81 LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule();
82
83 IConfigSource config = new IniConfigSource();
84 config.AddConfig("Chat");
85 IConfig modulesConfig = config.AddConfig("Modules");
86 modulesConfig.Set("EntityTransferModule", etmA.Name);
87 modulesConfig.Set("SimulationServices", lscm.Name);
88
89 SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm);
90 SceneHelpers.SetupSceneModules(sceneA, config, new CapabilitiesModule(), etmA, new ChatModule());
91 SceneHelpers.SetupSceneModules(sceneB, config, new CapabilitiesModule(), etmB, new ChatModule());
92 }
93
94 /// <summary>
95 /// Tests chat between neighbour regions on the east-west axis
96 /// </summary>
97 /// <remarks>
98 /// Really, this is a combination of a child agent position update test and a chat range test. These need
99 /// to be separated later on.
100 /// </remarks>
101 [Test]
102 public void TestInterRegionChatDistanceEastWest()
103 {
104 TestHelpers.InMethod();
105// TestHelpers.EnableLogging();
106
107 UUID sp1Uuid = TestHelpers.ParseTail(0x11);
108 UUID sp2Uuid = TestHelpers.ParseTail(0x12);
109
110 Vector3 sp1Position = new Vector3(6, 128, 20);
111 Vector3 sp2Position = new Vector3(250, 128, 20);
112
113 SceneHelpers sh = new SceneHelpers();
114 TestScene sceneWest = sh.SetupScene("sceneWest", TestHelpers.ParseTail(0x1), 1000, 1000);
115 TestScene sceneEast = sh.SetupScene("sceneEast", TestHelpers.ParseTail(0x2), 1001, 1000);
116
117 SetupNeighbourRegions(sceneWest, sceneEast);
118
119 ScenePresence sp1 = SceneHelpers.AddScenePresence(sceneEast, sp1Uuid);
120 TestClient sp1Client = (TestClient)sp1.ControllingClient;
121
122 // If we don't set agents to flying, test will go wrong as they instantly fall to z = 0.
123 // TODO: May need to create special complete no-op test physics module rather than basic physics, since
124 // physics is irrelevant to this test.
125 sp1.Flying = true;
126
127 // When sp1 logs in to sceneEast, it sets up a child agent in sceneWest and informs the sp2 client to
128 // make the connection. For this test, will simplify this chain by making the connection directly.
129 ScenePresence sp1Child = SceneHelpers.AddChildScenePresence(sceneWest, sp1Uuid);
130 TestClient sp1ChildClient = (TestClient)sp1Child.ControllingClient;
131
132 sp1.AbsolutePosition = sp1Position;
133
134 ScenePresence sp2 = SceneHelpers.AddScenePresence(sceneWest, sp2Uuid);
135 TestClient sp2Client = (TestClient)sp2.ControllingClient;
136 sp2.Flying = true;
137
138 ScenePresence sp2Child = SceneHelpers.AddChildScenePresence(sceneEast, sp2Uuid);
139 TestClient sp2ChildClient = (TestClient)sp2Child.ControllingClient;
140
141 sp2.AbsolutePosition = sp2Position;
142
143 // We must update the scenes in order to make the root new root agents trigger position updates in their
144 // children.
145 sceneWest.Update(1);
146 sceneEast.Update(1);
147
148 // Check child positions are correct.
149 Assert.AreEqual(
150 new Vector3(sp1Position.X + sceneEast.RegionInfo.RegionSizeX, sp1Position.Y, sp1Position.Z),
151 sp1ChildClient.SceneAgent.AbsolutePosition);
152
153 Assert.AreEqual(
154 new Vector3(sp2Position.X - sceneWest.RegionInfo.RegionSizeX, sp2Position.Y, sp2Position.Z),
155 sp2ChildClient.SceneAgent.AbsolutePosition);
156
157 string receivedSp1ChatMessage = "";
158 string receivedSp2ChatMessage = "";
159
160 sp1ChildClient.OnReceivedChatMessage
161 += (message, type, fromPos, fromName, fromAgentID, ownerID, source, audible) => receivedSp1ChatMessage = message;
162 sp2ChildClient.OnReceivedChatMessage
163 += (message, type, fromPos, fromName, fromAgentID, ownerID, source, audible) => receivedSp2ChatMessage = message;
164
165 TestUserInRange(sp1Client, "ello darling", ref receivedSp2ChatMessage);
166 TestUserInRange(sp2Client, "fantastic cats", ref receivedSp1ChatMessage);
167
168 sp1Position = new Vector3(30, 128, 20);
169 sp1.AbsolutePosition = sp1Position;
170 sceneEast.Update(1);
171
172 // Check child position is correct.
173 Assert.AreEqual(
174 new Vector3(sp1Position.X + sceneEast.RegionInfo.RegionSizeX, sp1Position.Y, sp1Position.Z),
175 sp1ChildClient.SceneAgent.AbsolutePosition);
176
177 TestUserOutOfRange(sp1Client, "beef", ref receivedSp2ChatMessage);
178 TestUserOutOfRange(sp2Client, "lentils", ref receivedSp1ChatMessage);
179 }
180
181 /// <summary>
182 /// Tests chat between neighbour regions on the north-south axis
183 /// </summary>
184 /// <remarks>
185 /// Really, this is a combination of a child agent position update test and a chat range test. These need
186 /// to be separated later on.
187 /// </remarks>
188 [Test]
189 public void TestInterRegionChatDistanceNorthSouth()
190 {
191 TestHelpers.InMethod();
192 // TestHelpers.EnableLogging();
193
194 UUID sp1Uuid = TestHelpers.ParseTail(0x11);
195 UUID sp2Uuid = TestHelpers.ParseTail(0x12);
196
197 Vector3 sp1Position = new Vector3(128, 250, 20);
198 Vector3 sp2Position = new Vector3(128, 6, 20);
199
200 SceneHelpers sh = new SceneHelpers();
201 TestScene sceneNorth = sh.SetupScene("sceneNorth", TestHelpers.ParseTail(0x1), 1000, 1000);
202 TestScene sceneSouth = sh.SetupScene("sceneSouth", TestHelpers.ParseTail(0x2), 1000, 1001);
203
204 SetupNeighbourRegions(sceneNorth, sceneSouth);
205
206 ScenePresence sp1 = SceneHelpers.AddScenePresence(sceneNorth, sp1Uuid);
207 TestClient sp1Client = (TestClient)sp1.ControllingClient;
208
209 // If we don't set agents to flying, test will go wrong as they instantly fall to z = 0.
210 // TODO: May need to create special complete no-op test physics module rather than basic physics, since
211 // physics is irrelevant to this test.
212 sp1.Flying = true;
213
214 // When sp1 logs in to sceneEast, it sets up a child agent in sceneNorth and informs the sp2 client to
215 // make the connection. For this test, will simplify this chain by making the connection directly.
216 ScenePresence sp1Child = SceneHelpers.AddChildScenePresence(sceneSouth, sp1Uuid);
217 TestClient sp1ChildClient = (TestClient)sp1Child.ControllingClient;
218
219 sp1.AbsolutePosition = sp1Position;
220
221 ScenePresence sp2 = SceneHelpers.AddScenePresence(sceneSouth, sp2Uuid);
222 TestClient sp2Client = (TestClient)sp2.ControllingClient;
223 sp2.Flying = true;
224
225 ScenePresence sp2Child = SceneHelpers.AddChildScenePresence(sceneNorth, sp2Uuid);
226 TestClient sp2ChildClient = (TestClient)sp2Child.ControllingClient;
227
228 sp2.AbsolutePosition = sp2Position;
229
230 // We must update the scenes in order to make the root new root agents trigger position updates in their
231 // children.
232 sceneNorth.Update(1);
233 sceneSouth.Update(1);
234
235 // Check child positions are correct.
236 Assert.AreEqual(
237 new Vector3(sp1Position.X, sp1Position.Y - sceneNorth.RegionInfo.RegionSizeY, sp1Position.Z),
238 sp1ChildClient.SceneAgent.AbsolutePosition);
239
240 Assert.AreEqual(
241 new Vector3(sp2Position.X, sp2Position.Y + sceneSouth.RegionInfo.RegionSizeY, sp2Position.Z),
242 sp2ChildClient.SceneAgent.AbsolutePosition);
243
244 string receivedSp1ChatMessage = "";
245 string receivedSp2ChatMessage = "";
246
247 sp1ChildClient.OnReceivedChatMessage
248 += (message, type, fromPos, fromName, fromAgentID, ownerID, source, audible) => receivedSp1ChatMessage = message;
249 sp2ChildClient.OnReceivedChatMessage
250 += (message, type, fromPos, fromName, fromAgentID, ownerID, source, audible) => receivedSp2ChatMessage = message;
251
252 TestUserInRange(sp1Client, "ello darling", ref receivedSp2ChatMessage);
253 TestUserInRange(sp2Client, "fantastic cats", ref receivedSp1ChatMessage);
254
255 sp1Position = new Vector3(30, 128, 20);
256 sp1.AbsolutePosition = sp1Position;
257 sceneNorth.Update(1);
258
259 // Check child position is correct.
260 Assert.AreEqual(
261 new Vector3(sp1Position.X, sp1Position.Y - sceneNorth.RegionInfo.RegionSizeY, sp1Position.Z),
262 sp1ChildClient.SceneAgent.AbsolutePosition);
263
264 TestUserOutOfRange(sp1Client, "beef", ref receivedSp2ChatMessage);
265 TestUserOutOfRange(sp2Client, "lentils", ref receivedSp1ChatMessage);
266 }
267
268 private void TestUserInRange(TestClient speakClient, string testMessage, ref string receivedMessage)
269 {
270 receivedMessage = "";
271
272 speakClient.Chat(0, ChatTypeEnum.Say, testMessage);
273
274 Assert.AreEqual(testMessage, receivedMessage);
275 }
276
277 private void TestUserOutOfRange(TestClient speakClient, string testMessage, ref string receivedMessage)
278 {
279 receivedMessage = "";
280
281 speakClient.Chat(0, ChatTypeEnum.Say, testMessage);
282
283 Assert.AreNotEqual(testMessage, receivedMessage);
284 }
285 }
286} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
index 7aa7123..2462ff8 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
@@ -428,7 +428,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
428 /// <summary> 428 /// <summary>
429 /// delegate for sending a grid instant message asynchronously 429 /// delegate for sending a grid instant message asynchronously
430 /// </summary> 430 /// </summary>
431 public delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID); 431 public delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result);
432 432
433 protected virtual void GridInstantMessageCompleted(IAsyncResult iar) 433 protected virtual void GridInstantMessageCompleted(IAsyncResult iar)
434 { 434 {
@@ -442,138 +442,87 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
442 { 442 {
443 GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsync; 443 GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsync;
444 444
445 d.BeginInvoke(im, result, UUID.Zero, GridInstantMessageCompleted, d); 445 d.BeginInvoke(im, result, GridInstantMessageCompleted, d);
446 } 446 }
447 447
448 /// <summary> 448 /// <summary>
449 /// Recursive SendGridInstantMessage over XMLRPC method. 449 /// Internal SendGridInstantMessage over XMLRPC method.
450 /// This is called from within a dedicated thread.
451 /// The first time this is called, prevRegionHandle will be 0 Subsequent times this is called from
452 /// itself, prevRegionHandle will be the last region handle that we tried to send.
453 /// If the handles are the same, we look up the user's location using the grid.
454 /// If the handles are still the same, we end. The send failed.
455 /// </summary> 450 /// </summary>
456 /// <param name="prevRegionHandle"> 451 /// <remarks>
457 /// Pass in 0 the first time this method is called. It will be called recursively with the last 452 /// This is called from within a dedicated thread.
458 /// regionhandle tried 453 /// </remarks>
459 /// </param> 454 private void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result)
460 protected virtual void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID)
461 { 455 {
462 UUID toAgentID = new UUID(im.toAgentID); 456 UUID toAgentID = new UUID(im.toAgentID);
463 457 UUID regionID;
464 PresenceInfo upd = null; 458 bool needToLookupAgent;
465
466 bool lookupAgent = false;
467 459
468 lock (m_UserRegionMap) 460 lock (m_UserRegionMap)
461 needToLookupAgent = !m_UserRegionMap.TryGetValue(toAgentID, out regionID);
462
463 while (true)
469 { 464 {
470 if (m_UserRegionMap.ContainsKey(toAgentID)) 465 if (needToLookupAgent)
471 { 466 {
472 upd = new PresenceInfo(); 467 PresenceInfo[] presences = PresenceService.GetAgents(new string[] { toAgentID.ToString() });
473 upd.RegionID = m_UserRegionMap[toAgentID];
474 468
475 // We need to compare the current regionhandle with the previous region handle 469 UUID foundRegionID = UUID.Zero;
476 // or the recursive loop will never end because it will never try to lookup the agent again
477 if (prevRegionID == upd.RegionID)
478 {
479 lookupAgent = true;
480 }
481 }
482 else
483 {
484 lookupAgent = true;
485 }
486 }
487
488 470
489 // Are we needing to look-up an agent? 471 if (presences != null)
490 if (lookupAgent)
491 {
492 // Non-cached user agent lookup.
493 PresenceInfo[] presences = PresenceService.GetAgents(new string[] { toAgentID.ToString() });
494 if (presences != null && presences.Length > 0)
495 {
496 foreach (PresenceInfo p in presences)
497 { 472 {
498 if (p.RegionID != UUID.Zero) 473 foreach (PresenceInfo p in presences)
499 { 474 {
500 upd = p; 475 if (p.RegionID != UUID.Zero)
501 break; 476 {
477 foundRegionID = p.RegionID;
478 break;
479 }
502 } 480 }
503 } 481 }
504 }
505 482
506 if (upd != null) 483 // If not found or the found region is the same as the last lookup, then message is undeliverable
507 { 484 if (foundRegionID == UUID.Zero || foundRegionID == regionID)
508 // check if we've tried this before.. 485 break;
509 // This is one way to end the recursive loop 486 else
510 // 487 regionID = foundRegionID;
511 if (upd.RegionID == prevRegionID)
512 {
513 // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
514 HandleUndeliverableMessage(im, result);
515 return;
516 }
517 } 488 }
518 else 489
490 GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, regionID);
491 if (reginfo == null)
519 { 492 {
520 // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message"); 493 m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to find region {0}", regionID);
521 HandleUndeliverableMessage(im, result); 494 break;
522 return;
523 } 495 }
524 }
525 496
526 if (upd != null) 497 // Try to send the message to the agent via the retrieved region.
527 { 498 Hashtable msgdata = ConvertGridInstantMessageToXMLRPC(im);
528 GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, 499 msgdata["region_handle"] = 0;
529 upd.RegionID); 500 bool imresult = doIMSending(reginfo, msgdata);
530 if (reginfo != null) 501
502 // If the message delivery was successful, then cache the entry.
503 if (imresult)
531 { 504 {
532 Hashtable msgdata = ConvertGridInstantMessageToXMLRPC(im); 505 lock (m_UserRegionMap)
533 // Not actually used anymore, left in for compatibility
534 // Remove at next interface change
535 //
536 msgdata["region_handle"] = 0;
537 bool imresult = doIMSending(reginfo, msgdata);
538 if (imresult)
539 {
540 // IM delivery successful, so store the Agent's location in our local cache.
541 lock (m_UserRegionMap)
542 {
543 if (m_UserRegionMap.ContainsKey(toAgentID))
544 {
545 m_UserRegionMap[toAgentID] = upd.RegionID;
546 }
547 else
548 {
549 m_UserRegionMap.Add(toAgentID, upd.RegionID);
550 }
551 }
552 result(true);
553 }
554 else
555 { 506 {
556 // try again, but lookup user this time. 507 m_UserRegionMap[toAgentID] = regionID;
557 // Warning, this must call the Async version
558 // of this method or we'll be making thousands of threads
559 // The version within the spawned thread is SendGridInstantMessageViaXMLRPCAsync
560 // The version that spawns the thread is SendGridInstantMessageViaXMLRPC
561
562 // This is recursive!!!!!
563 SendGridInstantMessageViaXMLRPCAsync(im, result,
564 upd.RegionID);
565 } 508 }
509 result(true);
510 return;
566 } 511 }
567 else 512
568 { 513 // If we reach this point in the first iteration of the while, then we may have unsuccessfully tried
569 m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to find region {0}", upd.RegionID); 514 // to use a locally cached region ID. All subsequent attempts need to lookup agent details from
570 HandleUndeliverableMessage(im, result); 515 // the presence service.
571 } 516 needToLookupAgent = true;
572 }
573 else
574 {
575 HandleUndeliverableMessage(im, result);
576 } 517 }
518
519 // If we reached this point then the message was not deliverable. Remove the bad cache entry and
520 // signal the delivery failure.
521 lock (m_UserRegionMap)
522 m_UserRegionMap.Remove(toAgentID);
523
524 // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
525 HandleUndeliverableMessage(im, result);
577 } 526 }
578 527
579 /// <summary> 528 /// <summary>
@@ -584,7 +533,6 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
584 /// <returns>Bool if the message was successfully delivered at the other side.</returns> 533 /// <returns>Bool if the message was successfully delivered at the other side.</returns>
585 protected virtual bool doIMSending(GridRegion reginfo, Hashtable xmlrpcdata) 534 protected virtual bool doIMSending(GridRegion reginfo, Hashtable xmlrpcdata)
586 { 535 {
587
588 ArrayList SendParams = new ArrayList(); 536 ArrayList SendParams = new ArrayList();
589 SendParams.Add(xmlrpcdata); 537 SendParams.Add(xmlrpcdata);
590 XmlRpcRequest GridReq = new XmlRpcRequest("grid_instant_message", SendParams); 538 XmlRpcRequest GridReq = new XmlRpcRequest("grid_instant_message", SendParams);