2009-06-14 121 views
3

我需要一個簡單的C#中的JSON-RPC 1.0客戶端,最好使用.NET 2.0或更高版本。 我檢出了JRock 0.9 他們有幾個樣本,包括雅虎閱讀器,但樣本演示JSON,而不是JSON-RPC。 我明白我可以使用任何可用的JSON解析器來實現RPC部分,如JRock或Microsoft的兩個解析器。我更喜歡現成的樣品。C#中JSON-RPC客戶端的示例代碼

回答

0

下面是通過Observables(Rx)公開的.net4客戶端的示例。 http://jsonrpc2.codeplex.com/SourceControl/changeset/view/13061#63133

這是一個幾乎完全相同的wp7客戶端,它也通過Rx公開。 http://jsonrpc2.codeplex.com/SourceControl/changeset/view/13061#282775

這兩個例子都是異步執行它們的工作,所以它們可能比你想要的更復雜,除非你想要異步的例子。 :)

祝你好運!

+0

。我確信我在這裏錯過了一些東西,你介意給我一些關於爲什麼將方法命名爲關鍵字是合法的更多信息?謝謝! – Rishi 2014-09-30 21:44:10

+0

你是指使用泛型方法嗎? http://msdn.microsoft.com/en-us/library/twcad0zb.aspx – 2014-10-01 15:34:23

4

上面的示例使用HTTP請求。這裏是與TCP工作的變種(未繳類是用於沒有返回值的要求只是一個空的類):

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Net; 
using Newtonsoft.Json.Linq; 
using AustinHarris.JsonRpc; 
using System.Linq; 
using System.Reactive.Linq; 
using System.Reactive.Subjects; 
using System.Reactive.Concurrency; 
using System.Net.Sockets; 
using System.Text; 

namespace JsonRpc 
{ 
    public class JsonRpcClient 
    { 
     private static object idLock = new object(); 
     private static int id = 0; 
     public Encoding encoding { get; set; } 

     public JsonRpcClient(IPEndPoint serviceEndpoint, Encoding encoding) 
     { 
      this.serviceEndPoint = serviceEndpoint; 
      this.encoding = encoding; 
     } 

     private static Stream CopyAndClose(Stream inputStream) 
     { 
      const int readSize = 256; 
      byte[] buffer = new byte[readSize]; 
      MemoryStream ms = new MemoryStream(); 

      int count = inputStream.Read(buffer, 0, readSize); 
      while (count > 0) 
      { 
       ms.Write(buffer, 0, count); 
       count = inputStream.Read(buffer, 0, readSize); 
      } 
      ms.Position = 0; 
      inputStream.Close(); 
      return ms; 
     } 

     public IObservable<JsonResponse<T>> InvokeWithScheduler<T>(string method, object arg, IScheduler scheduler) 
     { 
      var req = new AustinHarris.JsonRpc.JsonRequest() 
      { 
       Method = method, 
       Params = new object[] { arg } 
      }; 
      return InvokeRequestWithScheduler<T>(req, scheduler); 
     } 

     public IObservable<JsonResponse<T>> InvokeSingleArgument<T>(string method, object arg) 
     { 
      var req = new AustinHarris.JsonRpc.JsonRequest() 
      { 
       Method = method, 
       Params = new object[] { arg } 
      }; 
      return InvokeRequest<T>(req); 
     } 

     public IObservable<JsonResponse<T>> InvokeWithScheduler<T>(string method, object[] args, IScheduler scheduler) 
     { 
      var req = new AustinHarris.JsonRpc.JsonRequest() 
      { 
       Method = method, 
       Params = args 
      }; 
      return InvokeRequestWithScheduler<T>(req, scheduler); 
     } 

     public IObservable<JsonResponse<T>> Invoke<T>(string method, object[] args) 
     { 
      var req = new AustinHarris.JsonRpc.JsonRequest() 
      { 
       Method = method, 
       Params = args 
      }; 
      return InvokeRequest<T>(req); 
     } 

     public IObservable<JsonResponse<T>> InvokeRequestWithScheduler<T>(JsonRequest jsonRpc, IScheduler scheduler) 
     { 
      var res = Observable.Create<JsonResponse<T>>((obs) => 
       scheduler.Schedule(()=>{ 

        makeRequest<T>(jsonRpc, obs); 
       })); 

      return res; 
     } 

     public IObservable<JsonResponse<T>> InvokeRequest<T>(JsonRequest jsonRpc) 
     { 
      return InvokeRequestWithScheduler<T>(jsonRpc, ImmediateScheduler.Instance); 
     } 

     private string sendAndReceive(string messageToSend) { 
      string res = null; 

     // Data buffer for incoming data. 
     byte[] bytes = new byte[1024]; 

     // Connect to a remote device. 
     try { 
      // Create a TCP/IP socket. 
      Socket socket = new Socket(AddressFamily.InterNetwork, 
       SocketType.Stream, ProtocolType.Tcp); 

      // Connect the socket to the remote endpoint. Catch any errors. 
      try { 
       socket.Connect(this.serviceEndPoint); 

       Console.Write("Socket connected to "+socket.RemoteEndPoint.ToString()); 

       // Encode the data string into a byte array. 
       byte[] msg = encoding.GetBytes(messageToSend); 

       // Send the data through the socket. 
       int bytesSent = socket.Send(msg); 

       // Receive the response from the remote device. 
       int bytesRec = socket.Receive(bytes); 
       res = encoding.GetString(bytes,0,bytesRec); 
       Console.Write("Server response = "+res); 

       // Release the socket. 
       socket.Shutdown(SocketShutdown.Both); 
       socket.Close(); 

      } catch (ArgumentNullException ane) { 
       Console.Write("ArgumentNullException : "+ane.ToString()); 
      } catch (SocketException se) { 
       Console.Write("SocketException : " + se.ToString()); 
      } catch (Exception e) { 
       Console.Write("Unexpected exception : " + e.ToString()); 
      } 

     } catch (Exception e) { 
      Console.Write(e.ToString()); 
     } 
     return res; 
    } 

     private void makeRequest<T>(JsonRequest jsonRpc, IObserver<JsonResponse<T>> obs) 
     { 
      JsonResponse<T> rjson = null; 
      string sstream = ""; 
      try 
      { 
       int myId; 
       lock (idLock) 
       { 
        myId = ++id; 
       } 
       jsonRpc.Id = myId.ToString(); 
      } 
      catch (Exception ex) 
      { 
       obs.OnError(ex); 
      } 
      try 
      { 
       var json = Newtonsoft.Json.JsonConvert.SerializeObject(jsonRpc)+"\r\n"; 
       if (typeof(T).Equals(typeof(Nil))) 
       { 
        sendAndReceive(json); 
        rjson = new JsonResponse<T>(); 
       } 
       else 
       { 
        sstream = sendAndReceive(json); 
        rjson = Newtonsoft.Json.JsonConvert.DeserializeObject<JsonResponse<T>>(sstream); 
       } 
      } 
      catch (Exception ex) 
      { 
       obs.OnError(ex); 
      } 
      if (rjson == null) 
      { 
       string exceptionMessage = ""; 
       try 
       { 
        JObject jo = Newtonsoft.Json.JsonConvert.DeserializeObject(sstream) as JObject; 
        exceptionMessage = jo["Error"].ToString(); 
       } 
       catch(Exception ex){ 
        exceptionMessage = sstream+"\r\n"+ex.Message; 
       } 
       obs.OnError(new Exception(exceptionMessage)); 
      } 
      else 
      { 
       obs.OnNext(rjson); 
      } 
      obs.OnCompleted(); 
     } 

     public IPEndPoint serviceEndPoint { get; set; } 
    } 
} 
我無法纏繞我的頭圍繞一個名爲「援引 」方法