CXuesong / JsonRpc.Standard

An asynchronous .NET Standard library for JSON RPC client & server implementation.
Apache License 2.0
33 stars 16 forks source link

Client Over WebSocket #6

Open John0King opened 5 years ago

John0King commented 5 years ago

I need two way communication(the server need to send a Notification to my client, and it does not know client ip address) I can successfully connect the server via System.Net.WebSockets.ClientWebSocket, but It does not use Stream (it use a ArraySegment<byte>) Is that still possible to use this library?

John0King commented 5 years ago

To solve my current problem, I design a simple version of JsonRPC , it only support notification call , and it's peer to peer. http://www.simple-is-better.org/rpc/#differences-between-1-0-and-2-0 from this document, the JsonRPC 2.0 is not peer to peer anymore. It that true ?

CXuesong commented 5 years ago

I'm not sure what exactly peer-to-peer means in the context of JsonRPC, but two parties using JsonRPC 2.0 can still communicate duplexly as long as the channel is duplex. And each party can share a same channel both for RPC server and client, because when receiving messages from one side of the channel, you can never confuse a) a JsonRPC request/notification from other side with b) a JsonRPC response from other side for a request previsouly sent from this side. Thus you, at the end of one side of the pipe, just need to pick out these two kind of messages, and feed them to corresponding JsonRPC server/client handler.

For example, console is duplex, because stdin/stdout are actually two streams, and Language Server Protocol uses JsonRPC over stdio as communication protocol. LSP client (e.g. VSCode IDE) can do RPC invocation on LSP server (e.g. OmniSharp LSP server) and get response (e.g. get all the workspace symbols), while LSP server can also do RPC invocation on LSP client and get response (e.g. show confirmation dialog on LSP client). By invocation I mean either request or notification call.

For WebSocket-based LSP server/client implementation, you may consider derive a class from QueuedMessageReader/MessageWriter, and consume messages over WebSocket. Then you can plug your implementation class directly into StreamRpcClientHandler/StreamRpcServerHandler. I will do this work later this month, but regretfully, there is no guarantee on the time of completion.

John0King commented 5 years ago

@CXuesong Thanks for your answer. but I still a little bit confusing, Is that means as a WebSocket Client I need to use both JSON-RPC Client And Server ? and another question is that does any php or other language (including this one JsonRpc.AspNetCore) JsonRPC Server implementation support duplex (Is that the server call client side a standard for other language server implementation too) ? In my case , the Server side is written in php, and client side is written in .net , and it's killing me 😫. if both written in .net , the SignalR is good choice for me. Anyway , I still looking forward to this project.

CXuesong commented 5 years ago

Is that means as a WebSocket Client I need to use both JSON-RPC Client And Server ?

Yes, if you want your HTTP server to be able to make call to HTTP client side, in addition to calling HTTP server from client side. In this case, you also need both JSON-RPC client and server waiting on your HTTP server. Note that these calls can happen in one WebSocket connection.

Also note that LSP is just a higher-level protocol that happens to use JSON-RPC 2.0 as transport protocol. LSP requires LSP server can call LSP client and vice versa, so when implementing LSP, we usually use a pair of JSON-RPC server and client handler logic both on the LSP server, and on the LSP client. Thus at this degree, I believe JSON-RPC 2.0 itself is one-directional (A calls B, but B cannot call A). Yet we may well put a pair of JSON-RPC server and client to achieve bi-directional calls.

does any php or other language (including this one JsonRpc.AspNetCore) JsonRPC Server implementation support duplex (Is that the server call client side a standard for other language server implementation too) ?

When I used "duplex", I only meant "bi-directional calls". I don't think it's a common vocabulary when discussing JSON-RPC 😋

And if you are using WebSocket, I don't think JsonRpc.AspNetCore will work, because it's HttpRequest-based, and it must be sent from HTTP client to server. A new package based on WebSocket will do.

CXuesong commented 5 years ago

Okay so now we have CXuesong.JsonRpc.WebSockets package in v0.4.3, and now it's on NuGet.

I have an example on how to use it to setup a JSON-RPC server on WebSocket server with ASP.NET Core in WebTestApplication.

If you are going to use this package on your WebSocket client, keep in mind WebSocketMessageReader/WebSocketMessageWriter are derived from MessageReader/MessageWriter in JsonRpc.Streams package, so you may need to refer to the JsonRpc.Streams example to figure out how to use it with JsonRpcClientHandler or JsonRpcServerHandler, which is in ConsoleTestApp. (JSON-RPC server code | JSON-RPC client code)

So the rest of work is that you need to instantiate a WebSocket object before passing it to WebSocketMessageReader/...Writer.

And please note that being a WebSocket client does not necessarily means you couldn't be a JSON-RPC server.

John0King commented 5 years ago

@CXuesong Great work ! 👍

bacause the JsonRpc not suit for me (because the php side) , do you know any other protocol that work peer to peer. my simple version works, but not very well for get response