Class JsonRpc
- Namespace
- Nerdbank.JsonRpc
- Assembly
- Nerdbank.JsonRpc.dll
[TypeShape(Kind = TypeShapeKind.None)]
public class JsonRpc : IDisposableObservable, IDisposable, IJsonRpcClient
- Inheritance
-
JsonRpc
- Implements
- Inherited Members
Constructors
JsonRpc(JsonRpcPipeChannel)
Initializes a new instance of the JsonRpc class over a pipe channel.
public JsonRpc(JsonRpcPipeChannel channel)
Parameters
channelJsonRpcPipeChannelThe channel used to exchange messages.
JsonRpc(JsonRpcPipeChannel, JsonRpcOptions?)
Initializes a new instance of the JsonRpc class over a pipe channel.
public JsonRpc(JsonRpcPipeChannel channel, JsonRpcOptions? options)
Parameters
channelJsonRpcPipeChannelThe channel used to exchange messages.
optionsJsonRpcOptionsThe immutable configuration, which may be shared by other connections, or null to use the default options.
Properties
ActivitySource
Gets the activity source used to create JSON-RPC client and server activities.
public static ActivitySource ActivitySource { get; }
Property Value
Remarks
Subscribe to this source with ActivityListener or an OpenTelemetry tracer provider.
Completion
Gets a task that completes when the connection has shut down.
public Task Completion { get; }
Property Value
Remarks
Deliberate disposal and EOF between messages without pending outbound requests succeed. Other connection failures fault this task with the original cause. EOF with pending requests faults it with EndOfStreamException.
IsDisposed
Gets a value indicating whether deliberate or automatic shutdown has begun.
public bool IsDisposed { get; }
Property Value
JoinableTaskFactory
Gets or initializes the JoinableTaskFactory to participate in to mitigate deadlocks with the main thread.
public JoinableTaskFactory? JoinableTaskFactory { get; init; }
Property Value
- JoinableTaskFactory
Defaults to null.
Remarks
When set, outbound requests carry a token that identifies the caller's JoinableTask (if any), and inbound requests that carry such a token are dispatched within a JoinableTask that is joined to it. This allows a remote party to call back into this process and reach the main thread while the original caller blocks it waiting on the outbound request.
The token is exchanged as the top-level joinableTaskToken JSON-RPC envelope property, compatible with StreamJsonRpc.
Initialize this property before calling Start().
JoinableTaskTracker
Gets or initializes the JoinableTaskTokenTracker used to forward JoinableTask tokens from inbound requests to outbound requests when JoinableTaskFactory is null.
public JoinableTaskTokenTracker JoinableTaskTracker { get; init; }
Property Value
- JoinableTaskTokenTracker
Defaults to an instance shared with all other JsonRpc instances that do not set this property.
Remarks
This property is ignored when JoinableTaskFactory is set.
Set this only in advanced scenarios where one process has many JsonRpc instances connected to different remote parties and correlating tokens across them is undesirable. Initialize this property before calling Start().
Logger
Gets or initializes the logger for request, connection, and transport diagnostics.
public ILogger Logger { get; init; }
Property Value
Remarks
Setting this property also configures the underlying channel to use the same logger.
MarshaledProxyOptions
Gets or initializes the options used for proxies implicitly created for RPC-marshalable objects.
public JsonRpcProxyOptions MarshaledProxyOptions { get; init; }
Property Value
- JsonRpcProxyOptions
Defaults to Default, the same naming convention used for ordinary RPC proxies.
Remarks
To communicate with StreamJsonRpc's default RPC-marshalable objects, set this property to
new() { MethodNameTransform = CommonMethodNameTransforms.Identity } in the JsonRpc object initializer.
This does not change options for proxies attached through Attach<T>(JsonRpcProxyOptions?).
Exceptions
- ArgumentNullException
Thrown when set to null.
MarshaledTargetOptions
Gets or initializes the options used when implicitly registering RPC-marshalable targets.
public JsonRpcTargetOptions MarshaledTargetOptions { get; init; }
Property Value
- JsonRpcTargetOptions
Defaults to Default, the same naming convention used for ordinary RPC targets.
Remarks
To communicate with StreamJsonRpc's default RPC-marshalable objects, set this property to
new() { MethodNameTransform = CommonMethodNameTransforms.Identity } in the JsonRpc object initializer.
This does not change options for targets registered through AddRpcTarget<T>(T, ITypeShape<T>, JsonRpcTargetOptions?).
Exceptions
- ArgumentNullException
Thrown when set to null.
MaximumMessageSize
Gets or initializes the maximum encoded message size, in bytes.
public int MaximumMessageSize { get; init; }
Property Value
- int
Defaults to 8 MiB. The built-in JSON and MessagePack channels apply this limit to received messages; the JSON channel also applies it to sent messages.
Exceptions
- ArgumentOutOfRangeException
Thrown when set to zero or a negative value.
MultiplexingStream
Gets or initializes the multiplexing stream used to send and receive out-of-band streams.
public MultiplexingStream? MultiplexingStream { get; init; }
Property Value
Remarks
Initialize this property before calling Start().
Options
Gets the immutable options used to configure this connection.
public JsonRpcOptions Options { get; }
Property Value
State
Gets the connection's lifecycle state, retaining the original shutdown mode after disposal.
public JsonRpcState State { get; }
Property Value
SynchronizationContext
Gets or initializes the SynchronizationContext that schedules the start of each inbound RPC method invocation.
public SynchronizationContext? SynchronizationContext { get; init; }
Property Value
- SynchronizationContext
Defaults to a private NonConcurrentSynchronizationContext instance (configured as non-sticky) that guarantees inbound method invocations begin in the order the remote party sent the requests.
Remarks
With the default value, inbound requests are dispatched on the thread pool, one at a time, in the order they arrive. Because the default context is non-sticky, it does not become Current while a method runs. As soon as a method yields at its first await (or returns), the next queued method may begin. Long-running methods therefore execute and complete concurrently with each other and in any order; only the order in which they start is guaranteed to match the order the client sent them.
Set this property to null to remove the ordering guarantee entirely. Each inbound invocation is then queued to the thread pool independently, so invocations may begin in any order and with full concurrency. This offers the highest throughput and is appropriate when the order in which methods start does not matter.
Alternatively, initialize this property with your own SynchronizationContext (for example, one that marshals to an application's main thread) to have every inbound method invocation begin execution on that context. A context that runs callbacks one at a time preserves the ordering guarantee described above; one that runs them concurrently does not. As with the default, a method's continuations after its first await are subject to normal await semantics and only return to this context if the context applies itself as Current and the method does not use ConfigureAwait(bool) with false.
Work that precedes the invocation (such as request parsing and cancellation bookkeeping) always runs on the reader loop in message order and is unaffected by this property.
Inbound $/cancelRequest notifications are exempt from this property and always begin on the thread pool.
Because their purpose is to interrupt work that is already running, queueing them behind that work would prevent
a handler that occupies the dispatcher without yielding from ever being canceled.
TerminationException
Gets the original connection-loss cause, or null if no connection loss occurred.
public Exception? TerminationException { get; }
Property Value
Remarks
Retained after a user calls Dispose(), including EOF for which Completion succeeded.
Methods
AddRpcTarget<T>(T, JsonRpcTargetOptions?)
Registers a local object's public instance methods as JSON-RPC targets, invoked when incoming requests match their JSON-RPC method names.
public void AddRpcTarget<T>(T target, JsonRpcTargetOptions? options = null) where T : IShapeable<T>
Parameters
targetTThe object whose methods should be invoked in response to matching incoming requests and notifications.
optionsJsonRpcTargetOptionsOptions controlling method name resolution for this target. When null, default options are used.
Type Parameters
TThe statically shaped type describing which members of
targetto register.
Remarks
Register all initial targets before calling Start() so the listener is ready to dispatch every method as soon as it begins reading messages.
AddRpcTarget<T>(T, ITypeShape<T>, JsonRpcTargetOptions?)
Registers a local object's public instance methods as JSON-RPC targets, invoked when incoming requests match their JSON-RPC method names.
public void AddRpcTarget<T>(T target, ITypeShape<T> shape, JsonRpcTargetOptions? options = null)
Parameters
targetTThe object whose methods should be invoked in response to matching incoming requests and notifications.
shapeITypeShape<T>The type shape describing
target's methods.optionsJsonRpcTargetOptionsOptions controlling method name resolution for this target. When null, default options are used.
Type Parameters
TThe type describing which members of
targetto register.
Remarks
Register all initial targets before calling Start() so the listener is ready to dispatch every method as soon as it begins reading messages.
Attach(Type, JsonRpcProxyOptions?)
Attaches a generated client proxy for an RPC contract interface to this JSON-RPC connection.
public object Attach(Type interfaceType, JsonRpcProxyOptions? options = null)
Parameters
interfaceTypeTypeThe RPC contract interface to proxy.
optionsJsonRpcProxyOptionsOptions controlling argument encoding for this proxy.
Returns
- object
A generated proxy instance that implements
interfaceType.
Remarks
The generated proxy factory is looked up once per interface and cached. When the interface is known at compile time, Attach<T>(JsonRpcProxyOptions?) is slightly faster because it avoids the dictionary lookup.
Attach<T>(JsonRpcProxyOptions?)
Attaches a generated client proxy for an RPC contract interface to this JSON-RPC connection.
public T Attach<T>(JsonRpcProxyOptions? options = null)
Parameters
optionsJsonRpcProxyOptionsOptions controlling argument encoding for this proxy.
Returns
- T
A generated proxy instance that implements
T.
Type Parameters
TThe RPC contract interface to proxy.
CreateArguments(bool, int, CancellationToken)
Creates a serializer-neutral builder for named or positional arguments.
public JsonRpcArgumentsBuilder CreateArguments(bool named, int count, CancellationToken cancellationToken = default)
Parameters
namedboolWhether to use named arguments.
countintThe exact number of arguments to write.
cancellationTokenCancellationTokenA token used when serializing all arguments.
Returns
- JsonRpcArgumentsBuilder
An argument builder using this client's serializer.
CreateBatch()
Creates a one-shot builder for sending multiple JSON-RPC requests and notifications as one protocol payload.
public JsonRpcBatch CreateBatch()
Returns
- JsonRpcBatch
A batch builder associated with this JSON-RPC connection.
Dispose()
Deliberately disposes this connection and rejects subsequent calls with ObjectDisposedException.
public void Dispose()
Remarks
Preserves any prior connection-loss cause in TerminationException and does not overwrite the original State or Completion outcome. Await Completion to observe asynchronous teardown.
NotifyAsync(string, JsonRpcValue, CancellationToken)
Sends a notification with arguments already serialized using the channel's selected encoding.
public ValueTask NotifyAsync(string method, JsonRpcValue arguments, CancellationToken cancellationToken)
Parameters
methodstringThe name of the remote method to invoke.
argumentsJsonRpcValueThe pre-serialized arguments payload.
cancellationTokenCancellationTokenA token whose cancellation is observed before the notification is posted.
Returns
- ValueTask
A task that completes when the notification has been accepted by the outbound channel.
Remarks
Consume the returned awaitable once. To share it, await it repeatedly, or compose it with other Tasks,
call AsTask() or Preserve() once and retain the returned awaitable instead of the original.
It may be backed by a pooled source that is recycled after consumption.
NotifyAsync<TArg>(string, in TArg, ITypeShape<TArg>, CancellationToken)
public ValueTask NotifyAsync<TArg>(string method, in TArg arguments, ITypeShape<TArg> argShape, CancellationToken cancellationToken)
Parameters
methodstringargumentsTArgargShapeITypeShape<TArg>cancellationTokenCancellationToken
Returns
Type Parameters
TArg
NotifyAsync<TArg>(string, in TArg, CancellationToken)
public ValueTask NotifyAsync<TArg>(string method, in TArg arguments, CancellationToken cancellationToken) where TArg : IShapeable<TArg>
Parameters
methodstringargumentsTArgcancellationTokenCancellationToken
Returns
Type Parameters
TArg
RequestAsync(string, JsonRpcValue, CancellationToken)
Sends a request with arguments already serialized using the channel's selected encoding.
public ValueTask RequestAsync(string method, JsonRpcValue arguments, CancellationToken cancellationToken)
Parameters
methodstringThe name of the remote method to invoke.
argumentsJsonRpcValueThe pre-serialized arguments payload.
cancellationTokenCancellationTokenA token whose cancellation should be propagated to the remote endpoint.
Returns
- ValueTask
A task that completes when the remote endpoint sends its response.
Remarks
Consume the returned awaitable once. To share it, await it repeatedly, or compose it with other Tasks,
call AsTask() or Preserve() once and retain the returned awaitable instead of the original.
It may be backed by a pooled source that is recycled after consumption.
A remote RequestCancelled response throws OperationCanceledException.
Cancellation exceptions include cancellationToken only if it is canceled.
Unrequested remote cancellation has a message explaining that the remote party canceled processing without caller-requested cancellation.
The original remote error is retained as a JsonRpcException inner exception; other remote errors throw JsonRpcException.
RequestAsync<TResult>(string, JsonRpcValue, ITypeShape<TResult>, CancellationToken)
Sends a request with arguments already serialized using the channel's selected encoding.
public ValueTask<TResult> RequestAsync<TResult>(string method, JsonRpcValue arguments, ITypeShape<TResult> resultShape, CancellationToken cancellationToken)
Parameters
methodstringThe name of the remote method to invoke.
argumentsJsonRpcValueThe pre-serialized arguments payload.
resultShapeITypeShape<TResult>The type shape describing
TResult.cancellationTokenCancellationTokenA token whose cancellation should be propagated to the remote endpoint.
Returns
- ValueTask<TResult>
A task that completes with the result returned by the remote endpoint.
Type Parameters
TResultThe expected result type.
Remarks
Consume the returned awaitable once. To share it, await it repeatedly, or compose it with other Tasks,
call AsTask() or Preserve() once and retain the returned awaitable instead of the original.
It may be backed by a pooled source that is recycled after consumption.
A remote RequestCancelled response throws OperationCanceledException.
Cancellation exceptions include cancellationToken only if it is canceled.
Unrequested remote cancellation has a message explaining that the remote party canceled processing without caller-requested cancellation.
The original remote error is retained as a JsonRpcException inner exception; other remote errors throw JsonRpcException.
RequestAsync<TArg>(string, in TArg, ITypeShape<TArg>, CancellationToken)
public ValueTask RequestAsync<TArg>(string method, in TArg arguments, ITypeShape<TArg> argShape, CancellationToken cancellationToken)
Parameters
methodstringargumentsTArgargShapeITypeShape<TArg>cancellationTokenCancellationToken
Returns
Type Parameters
TArg
RequestAsync<TArg>(string, in TArg, CancellationToken)
public ValueTask RequestAsync<TArg>(string method, in TArg arguments, CancellationToken cancellationToken) where TArg : IShapeable<TArg>
Parameters
methodstringargumentsTArgcancellationTokenCancellationToken
Returns
Type Parameters
TArg
RequestAsync<TArg, TResult>(string, in TArg, ITypeShape<TArg>, ITypeShape<TResult>, CancellationToken)
public ValueTask<TResult> RequestAsync<TArg, TResult>(string method, in TArg arguments, ITypeShape<TArg> argShape, ITypeShape<TResult> resultShape, CancellationToken cancellationToken)
Parameters
methodstringargumentsTArgargShapeITypeShape<TArg>resultShapeITypeShape<TResult>cancellationTokenCancellationToken
Returns
- ValueTask<TResult>
Type Parameters
TArgTResult
RequestAsync<TArg, TResult>(string, in TArg, CancellationToken)
public ValueTask<TResult> RequestAsync<TArg, TResult>(string method, in TArg arguments, CancellationToken cancellationToken) where TArg : IShapeable<TArg> where TResult : IShapeable<TResult>
Parameters
methodstringargumentsTArgcancellationTokenCancellationToken
Returns
- ValueTask<TResult>
Type Parameters
TArgTResult
RequestAsync<TArg, TResult, TResultProvider>(string, in TArg, CancellationToken)
public ValueTask<TResult> RequestAsync<TArg, TResult, TResultProvider>(string method, in TArg arguments, CancellationToken cancellationToken) where TArg : IShapeable<TArg> where TResultProvider : IShapeable<TResult>
Parameters
methodstringargumentsTArgcancellationTokenCancellationToken
Returns
- ValueTask<TResult>
Type Parameters
TArgTResultTResultProvider
RevokeMarshaledObject(object)
Revokes every active marshaled relationship for an object owned by this connection.
public int RevokeMarshaledObject(object target)
Parameters
targetobjectThe previously marshaled target object.
Returns
- int
The number of handles revoked.
Remarks
This operation is object-wide: every handle issued for target is revoked, while handles
for other objects are unaffected. Revocation does not dispose target; its owner remains
responsible for its lifetime. Calls already dispatched remotely may complete.
Start()
Starts listening for and dispatching incoming messages.
public void Start()
Remarks
Call this after registering initial targets with AddRpcTarget<T>(T, ITypeShape<T>, JsonRpcTargetOptions?) to avoid rejecting incoming requests or dropping notifications for which no RPC target has yet been registered.