【问题标题】:Sample code for JSON-RPC client in C#C# 中 JSON-RPC 客户端的示例代码
【发布时间】:2009-06-14 08:43:01
【问题描述】:

我需要一个简单的 C# JSON-RPC 1.0 客户端,最好使用 .NET 2.0 或更高版本。 我检查了 JRock 0.9 他们有几个示例,包括 Yahoo 阅读器,但示例演示 JSON,而不是 JSON-RPC。 我知道我可以使用任何可用的 JSON 解析器来实现 RPC 部分,例如 Microsoft 的 JRock 或两个。我更喜欢现成的样品。

【问题讨论】:

    标签: c# client json-rpc


    【解决方案1】:

    2 Samples here

    有两种不同的实现。阅读整个线程+检查附件

    【讨论】:

      【解决方案2】:

      以上示例适用于 HTTP 请求。这是一个适用于 TCP 的变体(Nil 类只是一个用于没有返回值的请求的空类):

      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; }
          }
      }
      

      【讨论】:

      • 你能举个简单的例子来说明如何正确调用它吗?
      • ^或任何人? :-)
      【解决方案3】:

      这是一个通过 Observables (Rx) 公开的 .net4 客户端示例。 http://jsonrpc2.codeplex.com/SourceControl/changeset/view/13061#63133

      这是一个几乎相同的 wp7 客户端,它也通过 Rx 公开。 http://jsonrpc2.codeplex.com/SourceControl/changeset/view/13061#282775

      这两个示例都是异步执行的,因此它们可能比您正在寻找的更复杂,除非您当然想要异步示例。 :)

      祝你好运!

      【讨论】:

      • 我无法理解名为“Invoke”的方法。我确定我在这里遗漏了一些东西,您介意向我指出有关为什么将方法命名为关键字是合法的更多信息吗?谢谢!
      • 你指的是泛型方法的使用吗? msdn.microsoft.com/en-us/library/twcad0zb.aspx
      • 嗨,Austin,与其说是泛型方法,不如说是当方法是关键字时,它被命名为“Invoke”。我认为它被称为代理模式?我试图了解对它的需求以及编译器如何调用“Invoke”方法非常好。谢谢!
      猜你喜欢
      • 2010-10-17
      • 1970-01-01
      • 2011-07-24
      • 1970-01-01
      • 1970-01-01
      • 2016-09-15
      • 2023-03-10
      • 2011-06-28
      • 2020-06-09
      相关资源
      最近更新 更多