Pregunta

Necesito un cliente JSON-RPC 1.0 simple en C#, preferiblemente usando .NET 2.0 o posterior. Revisé a JRock 0.9 Tienen varias muestras, incluido Yahoo Reader, pero las muestras demo JSON, no JSON-RPC. Entiendo que podría implementar la parte RPC utilizando cualquiera de los analizadores JSON disponibles, como JRock o dos de Microsoft. Preferiría una muestra lista.

¿Fue útil?

Solución

2 muestras aquí

Hay dos implementaciones diferentes. Lea todo el hilo + verifique los archivos adjuntos

Otros consejos

Las muestras anteriores funcionan con solicitudes HTTP. Aquí hay una variante que funciona con TCP (la clase NIL es solo una clase vacía utilizada para solicitudes sin valor de retorno):

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

Aquí hay un ejemplo de un cliente .NET4 expuesto a través de observables (RX).http://jsonrpc2.codeplex.com/sourcecontrol/changeset/view/13061#63133

Aquí hay un cliente WP7 casi idéntico que también está expuesto a través de RX.http://jsonrpc2.codeplex.com/sourcecontrol/changeset/view/13061#282775

Ambos ejemplos hacen su trabajo de manera asincrónica, por lo que pueden ser más complicados de lo que está buscando, a menos que, por supuesto, quisiera ejemplos que fueran asincrónicos. :)

¡Buena suerte!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top