C# 中 JSON-RPC 客户端的示例代码

Posted

技术标签:

【中文标题】C# 中 JSON-RPC 客户端的示例代码【英文标题】:Sample code for JSON-RPC client in C# 【发布时间】: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 或两个。我更喜欢现成的样品。

【问题讨论】:

【参考方案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”方法非常好。谢谢!

以上是关于C# 中 JSON-RPC 客户端的示例代码的主要内容,如果未能解决你的问题,请参考以下文章

GAE Go Json-RPC 调用示例

用于 UDP 客户端的 Windows C 套接字编程

一个C#的tcp通讯示例小程序(含服务端与客户端)

与 GWT 客户端和 ASP.NET C# 服务器端的通信/传输协议

C# WebSocket 服务端示例代码 + HTML5客户端示例代码

Ember 数据 JSON-RPC 请求示例