Nethereum.Parity.Reactive
NuGet:
Nethereum.Parity.Reactive| Source:src/Nethereum.Parity.Reactive/Reactive (IObservable) subscriptions over Parity'sparity_subscribepub/sub
Overview
Nethereum.Parity.Reactive contains one class, ParityPubSubObservableSubscription<TResponse>. It takes any RpcRequest, re-sends it wrapped in a parity_subscribe request over a streaming client, and surfaces the subscription's responses as Rx observables. Use it when you are connected to a Parity / OpenEthereum node through a streaming transport (for example a WebSocket client implementing IStreamingClient) and want IObservable results for parity_subscribe. For the non-reactive parity_* and trace_* calls use Nethereum.Parity; the other Rx streams live in Nethereum.RPC.Reactive, whose RpcStreamingSubscriptionObservableHandler<T> this class derives from.
Installation
dotnet add package Nethereum.Parity.Reactive
Project references: Nethereum.Parity and Nethereum.RPC.Reactive; package reference System.Reactive 4.1.3. Target frameworks come from the build's ReactiveFrameworks property (net461, netstandard2.0, net6.0, net8.0, net9.0, net10.0 in the default build).
ParityPubSubObservableSubscription
Namespace Nethereum.Parity.Reactive.
public class ParityPubSubObservableSubscription<TResponse> : RpcStreamingSubscriptionObservableHandler<TResponse>
{
public ParityPubSubObservableSubscription(IStreamingClient client)
public Task SubscribeAsync(RpcRequest originalRequestToSubscribe, object id = null)
public RpcRequest BuildRequest(RpcRequest originalRequestToSubscribe, object id = null)
}
- The constructor passes an
EthUnsubscribeRequestBuilderto the base class, so unsubscribing sends the standard unsubscribe request, notparity_unsubscribe. BuildRequestdelegates toParitySubscribeRequestBuilderfromNethereum.Parity: the result is aparity_subscriberequest whose parameters are the original method name followed by the original parameters. A nullidbecomes a new GUID string.SubscribeAsyncbuilds that request and subscribes with it.
Inherited from RpcStreamingSubscriptionObservableHandler<TResponse> and RpcStreamingSubscriptionHandler<TResponse>:
public IObservable<string> GetSubscribeResponseAsObservable()
public IObservable<TResponse> GetSubscriptionDataResponsesAsObservable()
public IObservable<bool> GetUnsubscribeResponseAsObservable()
public Task UnsubscribeAsync()
public string SubscriptionId { get; protected set; }
public SubscriptionState SubscriptionState { get; protected set; }
Subscribing and observing the results:
var subscription = new ParityPubSubObservableSubscription<JToken>(streamingClient);
subscription.GetSubscribeResponseAsObservable().Subscribe(subscriptionIds.Add);
subscription.GetSubscriptionDataResponsesAsObservable().Subscribe(result => received.Add(result));
var balanceRequest = new RpcRequest(1, "eth_getBalance", Address, "latest");
await subscription.SubscribeAsync(balanceRequest, "sub-1");
The streaming client receives one parity_subscribe request whose first parameter is "eth_getBalance"; when the node answers with the subscription id, SubscriptionId is set and the subscribe observable emits it; each later notification for that id is emitted by the data observable. Unsubscribing sends the standard eth_unsubscribe request:
await subscription.UnsubscribeAsync();
Backed by ParityPubSubObservableSubscriptionTests.ShouldSubscribeThroughParitySubscribeAndObserveTheResults and ShouldUnsubscribeWithTheStandardUnsubscribeRequest (DocSection.ClientExtensions, parity-reactive) in tests/Nethereum.Parity.IntegrationTests. They use a fake IStreamingClient that answers the subscribe request with the id 0xsub1 and then pushes parity_subscription notifications, so no node is needed; streamingClient in a real application is a connected WebSocket (or other) IStreamingClient.