Клиент C # для JSON-RPC API - PullRequest
       26

Клиент C # для JSON-RPC API

0 голосов
/ 09 сентября 2018

Я пытаюсь отправить запросы в API, который говорит JSON-RPC. Я проверил сервер с помощью Curl:

> curl -v -d 'SOME_INVALID_REQUEST' http://erbium1.sytes.net:50001
 {"jsonrpc": "2.0", "error": {"code": -32700, "message": "invalid JSON"}, "id": null}

Некоторые запросы, которые меня интересуют, являются подписками, поэтому отправка запросов POST кажется непригодной для этого, потому что я не ожидаю, что сервер ответит мгновенно, а получит одно или несколько уведомлений.

Я пытаюсь поговорить с этим сервером, используя C #, но сервер никогда не отвечает. Для отправки сообщений я сделал следующее:

  1. Создано TcpClient
  2. Подключил клиента к серверу (erbium1.sytes.net, 50001)
  3. Go NetworkStream от подключенного клиента
  4. Написал в NetworkStream Когда я отправляю эти сообщения на сервер, функция обратного вызова read никогда не вызывается, поэтому я никогда не получаю ответы от сервера. Если я отправлю сообщения на порт 50002 (TLS) вместо 50001, сервер ответит пустой строкой.

Я предполагаю, что необработанное соединение TcpClient не отправляет сообщения с заголовками HTTP, поэтому сервер их просто отбрасывает? Если это так, что будет подходящим способом запроса подписок на сервер и сможет получать уведомления?

Какая разница между соединением TcpClient и WebSocket? Подойдет ли здесь WebSocket?

Ниже приведен пример моего кода:

// State object for receiving data from remote device.
public class ReceiverState {
    public ReceiverState(NetworkStream s) {
        this.stream = s;
    }
    public NetworkStream stream;
    public const int bufferSize = 1024;
    public byte[] buffer = new byte[bufferSize];
    public AutoResetEvent receivedEvent = new AutoResetEvent(false);
}



  static AutoResetEvent received = new AutoResetEvent(false);

  public static void PingServer(NetworkStream stream) {
      if (stream.CanWrite) {
          try {
              String rpc = "INVALID_REQUEST";
              Byte[] data = System.Text.Encoding.UTF8.GetBytes(rpc);
              stream.Write(data, 0, data.Length);
              stream.Flush();
              Console.WriteLine("Pinging...");
          } catch (Exception e) {
              Console.WriteLine(e.ToString());
          }
      } else {
          // TODO Throw an exception
          Console.WriteLine("Unable to write to stream");
      }
  }

  public static void BeginAsyncRead(NetworkStream stream, ReceiverState readState) {
      if (stream.CanRead) {
          try {
              stream.BeginRead(readState.buffer, 0, 1024,
                               new AsyncCallback(readCallBack),
                               readState);
          }
          catch (Exception e) {
              Console.WriteLine(e.ToString());
          }
      } else {
          // TODO Throw an exception
          Console.WriteLine("Unable to read from stream");
      }
  }

  private static void readCallBack(System.IAsyncResult ar) {
      // Get the state from AsyncResult
      ReceiverState state = (ReceiverState) ar.AsyncState;

      if(ar.IsCompleted){
          Int32 numBytes = state.stream.EndRead(ar);
          Console.WriteLine("Received : ");
          Console.WriteLine(Encoding.ASCII.GetString(state.buffer,0,numBytes+10));
          state.receivedEvent.Set();
      }
  }

  private static void synchronousRead(NetworkStream myNetworkStream) {
      if(myNetworkStream.CanRead){
          byte[] myReadBuffer = new byte[1024];
          StringBuilder myCompleteMessage = new StringBuilder();
          int numberOfBytesRead = 0;

          // Incoming message may be larger than the buffer size.
          do{
              numberOfBytesRead = myNetworkStream.Read(myReadBuffer, 0, myReadBuffer.Length);
              myCompleteMessage.AppendFormat("{0}", Encoding.ASCII.GetString(myReadBuffer, 0, numberOfBytesRead));
          }
          while(myNetworkStream.DataAvailable);
          // Print out the received message to the console.
          Console.WriteLine("You received the following message : " +
                            myCompleteMessage);
      }
      else{
          Console.WriteLine("Sorry.  You cannot read from this NetworkStream.");
      }
  }

  public static void Main(string[] args) {
    // Create a new TcpClient
    TcpClient client = new TcpClient();
    Console.WriteLine("Connecting...");
    client.Connect("electrum3.hachre.de", 50001);
    NetworkStream stream = client.GetStream();
    Stream inStream = new MemoryStream();
    ReceiverState readState = new ReceiverState(stream);
    readState.receivedEvent = received;
    BeginAsyncRead(stream, readState);
    PingServer(stream);
    received.WaitOne();
  }
...