qchateau / packio

An asynchronous msgpack-RPC and JSON-RPC library built on top of Boost.Asio.
https://qchateau.github.io/packio/
Mozilla Public License 2.0
138 stars 20 forks source link

Feature proposal - unsolicited notifications #71

Open weili-jiang opened 1 year ago

weili-jiang commented 1 year ago

I am currently using packio as a JSON RPC client in a commercial project. The server is a custom JSON RPC implementation that sends unsolicited notifications. This behaviour is outside the JSON RPC specification, but we have no control over the server. Other libraries have implemented this extension - see https://github.com/joncol/jcon-cpp as an example.

I have implemented the client-side support for this, extending the client class using the existing dispatcher class used by the server. We have been using this successfully over the last couple of months. What we have not done:

Before I do any further work - would you be interested in a PR for this feature?

qchateau commented 1 year ago

Hi,

While I don't mind evolution, I don't want to implement a behavior that is specific to packio, as I want to provide a standard implementation so that servers and clients can be implemented in different languages, using different libraries. I get that this feature would be opt-in, but the point still stands. If I implement your feature today and tomorrow someone else comes up with the same request, but a slightly different protocol, it would be embarassing.

You mention an extension used by other libraries (plural). Is there any kind of specification for it ? How many libraries support it ? Is this an extension that can be found in other languages ?

Before committing to a protocol to implement this feature, I'd like to asses how standard and reusable it would be

weili-jiang commented 1 year ago

Perhaps I did not describe it properly. It is more like bidirectional JSON RPC, where a server and client may exist on the same transport.

The basic concept is that while JSON RPC is client-server per request/response, there is no specific restriction that says a particular transport is stuck with a single server on one end and client on the other. The same socket may be used to send both client and server type messages. So actually, it is within JSON RPC specification, just a particular interpretation of it.

Some libraries, e.g. https://github.com/joncol/jcon-cpp simply allow you to send notifications from the server instance and handle them in the client. I went with this approach for packio as it represented minimal interface change to the existing API without breaking changes.

Most separate the server/client role from the transport entirely so you are free to do either on the same socket, e.g

.NET: https://www.npmjs.com/package/vscode-jsonrpc

JS: https://www.nuget.org/packages/streamjsonrpc

Perl: https://metacpan.org/pod/JSON::RPC2::TwoWay

Dart: https://pub.dev/packages/json_rpc_2

Go: https://pkg.go.dev/golang.org/x/tools/internal/jsonrpc2

If you Google bidirectional JSON RPC there are lots of examples.