microsoft / vs-streamjsonrpc

The StreamJsonRpc library offers JSON-RPC 2.0 over any .NET Stream, WebSocket, or Pipe. With bonus support for request cancellation, client proxy generation, and more.
Other
730 stars 149 forks source link

Rpc Server handling JSON string requests #1059

Closed slimshader closed 2 months ago

slimshader commented 2 months ago

Hi,

I'd like to use StreamJsonRpc in less usual way: executing methods on the target but from JSON string as an inout, I managed this snipped to partially work:

using StreamJsonRpc;
using System.Text;

public class RpcServer
{
    public int Add(int a, int b)
    {
        return a + b;
    }
}

class Program
{
    static async Task Main(string[] args)
    {
        var rpcServer = new RpcServer();

        string jsonRpcRequest = @"{
            ""jsonrpc"": ""2.0"",
            ""method"": ""Add"",
            ""params"": [1, 2],
            ""id"": 1
        }";

        jsonRpcRequest = $"Content-Length: {jsonRpcRequest.Length}\r\n\r\n{jsonRpcRequest}";

        var sendingStream = new MemoryStream();
        var receivingStream = new MemoryStream(Encoding.UTF8.GetBytes(jsonRpcRequest));

        var jsonRpc = JsonRpc.Attach(sendingStream, receivingStream, rpcServer);

        await jsonRpc.Completion;

        var result = sendingStream.ToArray();

        Console.ReadLine();
    }
}

In the debugger I see that Add() method is being called on RpcServer object, the problem I have is with the response. I am not able to read sendingStream as it is closed and ToArray() reuslts in empty array. How can I access the response?

slimshader commented 2 months ago

Update: I quickly coded custom Stream to serve as sending stream to debug the output and I noticed that Write() is never called on that stream so I guess the actual problem is not the fact that sendingStream is closed but that response is never actually written to it.

AArnott commented 2 months ago

While the library doesn't directly support what you're doing, I think you can achieve what you're hoping for. Check out our WebSocketMessageHandler for an example of non-Stream based I/O.

If you write your own class derived from MessageHandlerBase, you can create your own queues of incoming and outgoing messages.

slimshader commented 2 months ago

Thanks! Looks like what I need indeed although still wandering why my code isn’t working even tho there are no errors.

slimshader commented 2 months ago

Unfortunately, I just check out the example code for [WebSocketMessageHandler] and it does not look what I need. Will try figure out why stream-based code does not work as expected.