public Dictionary<string, object> DoServiceCall(string method, params object[] parameters)
{
var callId = Interlocked.Increment (ref this.callId);
var callObject = new Dictionary<string, object> {
{"id", callId},
{"method", method},
{"params", parameters}
};
#if DEBUG
Console.Error.Write ("Serializing JSON-RPC call object...");
Stopwatch s = new Stopwatch ();
s.Start ();
#endif
string jsonPayload = new Serializer (callObject).Serialize ();
#if DEBUG
s.Stop ();
Console.Error.WriteLine ("done in {0}.", s.Elapsed);
#endif
var serviceClient = new CookieClient ();
if (cookies != null) serviceClient.Cookies = cookies;
#if DEBUG
Console.Error.Write ("Making request...");
s.Reset ();
s.Start ();
#endif
byte[] returnData = serviceClient.UploadData (ServiceUri, Encoding.UTF8.GetBytes (jsonPayload));
#if DEBUG
s.Stop ();
Console.Error.WriteLine ("done in {0}.", s.Elapsed);
#endif
cookies = serviceClient.Cookies;
#if DEBUG
s.Reset ();
Console.Error.Write ("Decompressing result...");
s.Start ();
#endif
// All this because deluge always returns gzip data, despite what you send for Accept-Encoding.
var responseJson = new StreamReader (new GZipStream (new MemoryStream (returnData), CompressionMode.Decompress), Encoding.UTF8).ReadToEnd ();
#if DEBUG
s.Stop ();
Console.Error.WriteLine ("done in {0}.", s.Elapsed);
#endif
#if DEBUG
s.Reset ();
Console.Error.Write ("Deserializing result...");
s.Start ();
#endif
var response = new Deserializer (responseJson).Deserialize () as Dictionary<string, object>;
#if DEBUG
s.Stop ();
Console.Error.WriteLine ("done in {0}.", s.Elapsed);
#endif
if ((long) response["id"] != callId)
throw new ApplicationException (string.Format ("Response ID and original call ID don't match. Expected {0}, received {1}.", callId, response["id"]));
if (response["error"] != null)
throw new ApplicationException (string.Format ("Received error message from Deluge. Message: {0}", ((JsonObject) response["error"])["message"]));
return response;
}