/// <summary> /// JSON-RPC2リクエスト/レスポンスを処理する。 /// </summary> /// <param name="json">リクエスト/レスポンスのJSON文字列。</param> /// <returns>レスポンスのJSON文字列。通知やレスポンス無しの場合はnull。</returns> private async Task <JsonRpc2Response> DoMethodOrCallback(string json) { // TODO: バッチリクエスト/レスポンスには未対応 // レスポンス/リクエストかチェック JsonRpc2Response res; JsonRpc2Request req; if (JsonRpc2Response.TryParse(json, out res)) { // ※ intのIDしか送ってないのでintのIDしか返ってこない想定 var id = (int)(long)res.Id; Subject <object> subject; if (this.callback.TryGetValue(id, out subject)) { if (res.Error != null) { subject.OnError(res.Error); } else { subject.OnNext(Json.Serialize(res.Result)); subject.OnCompleted(); } this.callback.Remove(id); } return(null); } else if (JsonRpc2Request.TryParse(json, out req)) { // リクエストの場合はハンドラーに任せる try { var result = await this.RequestHandler(req.Method, req.Params, req.Id, this); if (req.Id != null) { return(new JsonRpc2Response(result, req.Id)); } return(null); } catch (Exception ex) { return(new JsonRpc2Response(JsonRpc2Exception.Convert(ex), req.Id)); } } throw new JsonRpc2Exception(JsonRpc2Exception.ErrorCode.ParseError); }
/// <summary> /// MiniJSONのオブジェクトをJSON-RPC2レスポンスとして解析する。 /// </summary> /// <param name="json">JSONオブジェクト。</param> /// <param name="response">解析したレスポンス。</param> /// <returns>解析できた場合true。</returns> public static bool TryParse(object json, out JsonRpc2Response response) { response = null; var res = json as IDictionary <string, object>; if (res == null) { return(false); } // 以下resultまたはerrorが必須。他はあれば取得(jsonrpcのバージョンチェックはしない) object jsonrpcObj; var jsonrpc = ""; if (res.TryGetValue("jsonrpc", out jsonrpcObj) && jsonrpcObj != null) { jsonrpc = jsonrpcObj.ToString(); } object id; res.TryGetValue("id", out id); object error; object result = null; if (res.TryGetValue("error", out error)) { response = new JsonRpc2Response(JsonRpc2Exception.Convert(error), id) { Jsonrpc = jsonrpc }; return(true); } else if (res.TryGetValue("result", out result)) { response = new JsonRpc2Response(result, id) { Jsonrpc = jsonrpc }; return(true); } return(false); }
/// <summary> /// WebSocketメッセージを受信する。 /// </summary> /// <param name="message">メッセージ。</param> private async void Receive(string message) { JsonRpc2Response res; try { res = await this.DoMethodOrCallback(message); } catch (Exception ex) { res = new JsonRpc2Response(JsonRpc2Exception.Convert(ex)); } if (res != null) { this.Send(res.ToJson()).Subscribe(); } }