Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions docfx/docs/proxies.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,28 @@ This changes the above example to something like this:

[!code-csharp[](../../samples/Proxies.cs#WithProxies)]

## Multiple proxies on one connection

Do not call static `JsonRpc.Attach<T>` multiple times on the same stream. Each static call creates a distinct <xref:StreamJsonRpc.JsonRpc> instance, and multiple instances cannot safely share one transport.

The following examples use this second RPC interface in addition to `ICalculator`.

[!code-csharp[](../../samples/Proxies.cs#MultipleProxiesInterfaces)]

When you need multiple client proxies over one connection, use one of these patterns:

1. Create one proxy that implements multiple interfaces at once.

[!code-csharp[](../../samples/Proxies.cs#MultipleProxiesPattern1)]

1. Create the <xref:StreamJsonRpc.JsonRpc> connection first, then call instance `Attach<T>` for each proxy.

[!code-csharp[](../../samples/Proxies.cs#MultipleProxiesPattern2)]

1. Create the first proxy with the static `Attach<T>` method, then get its <xref:StreamJsonRpc.JsonRpc> instance through <xref:StreamJsonRpc.IJsonRpcClientProxy> and create additional proxies with instance `Attach<T>` calls.

[!code-csharp[](../../samples/Proxies.cs#MultipleProxiesPattern3)]

## Proxy traits

Generated proxies have the following traits:
Expand Down
53 changes: 53 additions & 0 deletions samples/Proxies.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,59 @@ internal partial interface ICalculator
}
#endregion

#region MultipleProxiesInterfaces
[JsonRpcContract, GenerateShape(IncludeMethods = MethodShapeFlags.PublicInstance)]
internal partial interface IAdvancedCalculator
{
Task<int> MultiplyAsync(int a, int b);
}
#endregion

static async Task MultipleProxiesOption1(Stream rpcStream)
{
#region MultipleProxiesPattern3
ICalculator calculator = JsonRpc.Attach<ICalculator>(rpcStream);
JsonRpc rpc = ((IJsonRpcClientProxy)calculator).JsonRpc;
IAdvancedCalculator advancedCalculator = rpc.Attach<IAdvancedCalculator>();
Comment thread
AArnott marked this conversation as resolved.
using (calculator as IDisposable)
using (advancedCalculator as IDisposable)
{
int sum = await calculator.AddAsync(2, 5);
int product = await advancedCalculator.MultiplyAsync(2, 5);
}
#endregion
}

static async Task MultipleProxiesOption2(Stream rpcStream)
{
#region MultipleProxiesPattern2
using JsonRpc rpc = JsonRpc.Attach(rpcStream);
ICalculator calculator = rpc.Attach<ICalculator>();
IAdvancedCalculator advancedCalculator = rpc.Attach<IAdvancedCalculator>();
using (calculator as IDisposable)
using (advancedCalculator as IDisposable)
{
int sum = await calculator.AddAsync(2, 5);
int product = await advancedCalculator.MultiplyAsync(2, 5);
}
#endregion
}

static async Task MultipleProxiesOption3(Stream rpcStream)
{
#region MultipleProxiesPattern1
using JsonRpc rpc = JsonRpc.Attach(rpcStream);
object combinedProxy = rpc.Attach([typeof(ICalculator), typeof(IAdvancedCalculator)], options: null);
ICalculator calculator = (ICalculator)combinedProxy;
IAdvancedCalculator advancedCalculator = (IAdvancedCalculator)combinedProxy;
using (combinedProxy as IDisposable)
{
int sum = await calculator.AddAsync(2, 5);
int product = await advancedCalculator.MultiplyAsync(2, 5);
}
#endregion
}

partial class ServerWithoutInterface
{
#region ServerWithoutInterface
Expand Down
Loading