Adding C# Support. Badly tested currently, but kindof working
This commit is contained in:
130
templates/CSharp/JRpcClient.cs
Normal file
130
templates/CSharp/JRpcClient.cs
Normal file
@ -0,0 +1,130 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace __NAMESPACE__;
|
||||
|
||||
public class JRpcClient
|
||||
{
|
||||
private JRpcTransport Transport;
|
||||
private IDictionary<string, TaskCompletionSource<JsonNode?>> Requests;
|
||||
|
||||
public JRpcClient(JRpcTransport transport)
|
||||
{
|
||||
this.Transport = transport;
|
||||
this.Requests = new Dictionary<string, TaskCompletionSource<JsonNode?>>();
|
||||
|
||||
this.Transport.OnPacket += this.HandlePacket;
|
||||
}
|
||||
|
||||
private void HandlePacket(string packet)
|
||||
{
|
||||
try
|
||||
{
|
||||
var parsed = JsonNode.Parse(packet);
|
||||
if (parsed == null || (string?)parsed["jsonrpc"] != "2.0")
|
||||
return;
|
||||
|
||||
if (parsed["method"] != null)
|
||||
{ // Request or Notification
|
||||
if (parsed["id"] != null) // Requests are not supported on the Client
|
||||
return;
|
||||
//TODO: implement Notifications
|
||||
}
|
||||
else if (parsed["id"] != null && parsed["method"] == null)
|
||||
{
|
||||
// Response
|
||||
//TODO: Somehow remove this warning, since it has no meaning in this context.
|
||||
// ID has to be something, that was checked before
|
||||
var id = (string)parsed["id"]!;
|
||||
|
||||
var task = this.Requests[id];
|
||||
if (task == null)
|
||||
return; //This Request was not from here
|
||||
|
||||
if (parsed["error"] != null)
|
||||
{
|
||||
var err = parsed["error"].Deserialize<JRpcError>();
|
||||
if (err == null)
|
||||
{
|
||||
task.SetException(new JRpcException("Internal Server Error"));
|
||||
}
|
||||
else
|
||||
{
|
||||
task.SetException(err.ToException());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
task.SetResult(parsed["result"]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Ignoring invalid packet!
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//TODO: Maybe log exception, but don't break!
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<JsonNode?> SendRequestRaw(string method, JsonArray param)
|
||||
{
|
||||
var id = Guid.NewGuid().ToString();
|
||||
var request = new JsonObject
|
||||
{
|
||||
["jsonrpc"] = "2.0",
|
||||
["id"] = id,
|
||||
["method"] = method,
|
||||
["params"] = param
|
||||
};
|
||||
|
||||
var task = new TaskCompletionSource<JsonNode?>();
|
||||
this.Requests.Add(id, task);
|
||||
await this.Transport.Write(request.ToJsonString());
|
||||
|
||||
return await task.Task;
|
||||
}
|
||||
|
||||
public async Task<TResult?> SendRequest<TResult>(string method, JsonArray param)
|
||||
{
|
||||
var result = await this.SendRequestRaw(method, param);
|
||||
return result.Deserialize<TResult>();
|
||||
}
|
||||
|
||||
public async void SendNotification(string method, JsonArray param)
|
||||
{
|
||||
var not = new JsonObject
|
||||
{
|
||||
["jsonrpc"] = "2.0",
|
||||
["method"] = method,
|
||||
["params"] = param,
|
||||
};
|
||||
|
||||
await this.Transport.Write(not.ToJsonString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class JRpcError
|
||||
{
|
||||
public int code { get; set; }
|
||||
public string? message { get; set; }
|
||||
public JsonNode? data { get; set; }
|
||||
|
||||
public JRpcException ToException()
|
||||
{
|
||||
return new JRpcException(this.message!);
|
||||
}
|
||||
}
|
||||
|
||||
public class JRpcException : Exception
|
||||
{
|
||||
public JRpcException(string message) : base(message) { }
|
||||
}
|
Reference in New Issue
Block a user