Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic codegen of individual delegates to invoke RPC from client #673

Open
snikeguo opened this issue Jun 1, 2021 · 9 comments
Open

Dynamic codegen of individual delegates to invoke RPC from client #673

snikeguo opened this issue Jun 1, 2021 · 9 comments

Comments

@snikeguo
Copy link

snikeguo commented Jun 1, 2021

Contract:

public delegate Task DataChange(int v);

server:

do some thing.......
var dataChange=ServerJsonRpc.Attach<DataChange>( ClientInfo); //clientinfo is: client's stream /client's session(like ip and port) and so on
dataChange(newValue);
.......

client:

ClientJsonRpc.AddDelegate<DataChange>((v)=>{Console.WriteLine(...............)});

expect:When the server calls the DataChange delegate, the client will execute: Console.WriteLine(..........);

@snikeguo
Copy link
Author

snikeguo commented Jun 1, 2021

image

@snikeguo
Copy link
Author

snikeguo commented Jun 1, 2021

image

@AArnott AArnott changed the title I have a suggestion: Dynamic codegen of individual delegates to invoke RPC from client Jun 9, 2021
@AArnott
Copy link
Member

AArnott commented Jun 9, 2021

I suppose we could technically add a method to JsonRpc that would generate code for a delegate of a given signature that would invoke some method. Your samples don't include the generation of this delegate taking the name of the server method though -- only the signature is given. Where does the method name come from?

That said, we already have robust support for convenient client proxies via our code generator that implements whole interfaces. Can you use that instead of doing it on a per-delegate basis?

@AArnott
Copy link
Member

AArnott commented Jun 21, 2021

In StreamJsonRpc this would look like:

interface IMyRpcInterface
{
    Task<List<Order>> ListOrders(int employee, string employeeid);
    Task<List<Employee> ListEmployees();
    Task<List<Customer> ListCustomers();
}

On the server you could implement that interface.
On the client, you would then use:

IMyRpcInterface proxy = JsonRpc.Attach<IMyRpcInterface>(stream);
List<Employee> await proxy.ListEmployees();

@snikeguo
Copy link
Author

snikeguo commented Jun 24, 2021

In StreamJsonRpc this would look like:

interface IMyRpcInterface
{
    Task<List<Order>> ListOrders(int employee, string employeeid);
    Task<List<Employee> ListEmployees();
    Task<List<Customer> ListCustomers();
}

On the server you could implement that interface.
On the client, you would then use:

IMyRpcInterface proxy = JsonRpc.Attach<IMyRpcInterface>(stream);
List<Employee> await proxy.ListEmployees();

@AArnott
i know .it is : You are talking about the interface of Client calling Server (client call server).
I want to express is: Server pushes messages to Client through "delegate event"

public delegate Task DataChange(int v);


server:
do some thing.......
var dataChange=ServerJsonRpc.Attach<DataChange>( ClientInfo); //clientinfo is: client's stream /client's session(like ip and port) and so on
dataChange(newValue);
.......


client:

ClientJsonRpc.AddDelegate<DataChange>((v)=>{Console.WriteLine(...............)});


Currently, vs-streamjsonrpc does not support "delegate event"

@AArnott
Copy link
Member

AArnott commented Jun 24, 2021

Thanks for helping me understand you're interested in reverse-direction RPC.
JSON-RPC is fundamentally a p2p protocol. So there isn't really a client or a server as far as the RPC protocol is concerned. This means you can define an interface for generating a proxy for each direction. What you think as your client and server can each have a unique interface, and they can invoke each other. This provides you one option for your "server" to invoke the client given the method signature you want, and any such method can be put into a delegate in your own code.

Did you know that the RPC interface can include events?

interface IMyRpcInterface
{
    event EventHandler<ChangeDetails> EmployeesChanged;
    Task<List<Order>> ListOrders(int employee, string employeeid);
    Task<List<Employee> ListEmployees();
    Task<List<Customer> ListCustomers();
}

This can make it particularly convenient for a client/server paradigm designed interface to let the server call back to the client for notifications.

@snikeguo
Copy link
Author

yes ,i find a doc:
https://github.com/microsoft/vs-streamjsonrpc/blob/main/doc/dynamicproxy.md
but no sample.....only document
Where are examples of "delegate event"?

@AArnott
Copy link
Member

AArnott commented Jun 25, 2021

I'm sorry, I don't understand your question. Every event in C# is based on delegates. On the server and client you implement and add handlers to events as if it were ordinary C# code, and StreamJsonRpc makes them just work. If you're unfamiliar with events in C#, please learn that first then come back here if it works in the local case but not over RPC.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants