See More

using System; using System.Globalization; using System.Threading; using System.Threading.Tasks; using System.Reflection; using System.IO; using System.Collections.Generic; using System.Linq; using System.Text; using Newtonsoft.Json; namespace AustinHarris.JsonRpc { public static class JsonRpcProcessor { public static void Process(JsonRpcStateAsync async, object context = null) { Task.Factory.StartNew((_async) => { var tuple = (Tuple)_async; ProcessJsonRpcState(tuple.Item1, tuple.Item2); }, new Tuple(async,context)); } public static void Process(string sessionId, JsonRpcStateAsync async, object context = null) { var t = Task.Factory.StartNew((_async) => { var i = (Tuple)_async; ProcessJsonRpcState(i.Item1, i.Item2, i.Item3); }, new Tuple(sessionId, async, context)); } internal static void ProcessJsonRpcState(JsonRpcStateAsync async, object jsonRpcContext = null) { ProcessJsonRpcState(Handler.DefaultSessionId(), async, jsonRpcContext); } internal static void ProcessJsonRpcState(string sessionId, JsonRpcStateAsync async, object jsonRpcContext = null) { async.Result = ProcessInternal(sessionId, async.JsonRpc, jsonRpcContext); async.SetCompleted(); } public static Task Process(string jsonRpc, object context = null) { return Process(Handler.DefaultSessionId(), jsonRpc, context); } public static Task Process(string sessionId, string jsonRpc, object context = null) { return Task.Factory.StartNew((_) => { var tuple = (Tuple) _; return ProcessInternal(tuple.Item1, tuple.Item2, tuple.Item3); }, new Tuple(sessionId, jsonRpc, context)); } private static string ProcessInternal(string sessionId, string jsonRpc, object jsonRpcContext) { var handler = Handler.GetSessionHandler(sessionId); try { Tuple[] batch = null; if (isSingleRpc(jsonRpc)) { batch = new [] { Tuple.Create(JsonConvert.DeserializeObject(jsonRpc), new JsonResponse()) }; } else { batch = JsonConvert.DeserializeObject(jsonRpc) .Select(request => new Tuple(request, new JsonResponse())) .ToArray(); } if (batch.Length == 0) { return Newtonsoft.Json.JsonConvert.SerializeObject(new JsonResponse { Error = handler.ProcessParseException(jsonRpc, new JsonRpcException(3200, "Invalid Request", "Batch of calls was empty.")) }); } foreach (var tuple in batch) { var jsonRequest = tuple.Item1; var jsonResponse = tuple.Item2; if (jsonRequest == null) { jsonResponse.Error = handler.ProcessParseException(jsonRpc, new JsonRpcException(-32700, "Parse error", "Invalid JSON was received by the server. An error occurred on the server while parsing the JSON text.")); } else { jsonResponse.Id = jsonRequest.Id; if (jsonRequest.Method == null) { jsonResponse.Error = handler.ProcessParseException(jsonRpc, new JsonRpcException(-32600, "Invalid Request", "Missing property 'method'")); } else { var data = handler.Handle(jsonRequest, jsonRpcContext); if (data == null) continue; jsonResponse.Error = data.Error; jsonResponse.Result = data.Result; } } } var responses = new string[batch.Count(x=>x.Item2.Id!=null || x.Item2.Error != null)]; var idx = 0; foreach (var resp in batch.Where(x => x.Item2.Id != null || x.Item2.Error != null)) { responses[idx++] = JsonConvert.SerializeObject(resp.Item2); } return responses.Length == 0 ? string.Empty : responses.Length == 1 ? responses[0] : string.Format("[{0}]", string.Join(",", responses)); } catch (Exception ex) { return Newtonsoft.Json.JsonConvert.SerializeObject(new JsonResponse { Error = handler.ProcessParseException(jsonRpc, new JsonRpcException(-32700, "Parse error", ex)) }); } } private static bool isSingleRpc(string json) { for (int i = 0; i < json.Length; i++) { if (json[i] == '{') return true; else if (json[i] == '[') return false; } return true; } } }