WS
Nethereum provides websocket clients. They can be used instead of the default HTTP channel and to support subscriptions.
Websocket Clients
Typically, once established, a connection is maintained by the websocket client. This is both for performance reasons and also to support streaming subscriptions. The connection is closed on disposal of the client.
There are two main Websocket clients provided by Nethereum.
WebSocketClient
Related Nuget Packages:
- Nethereum.JsonRpc.WebSocketClient
- Nethereum.Web3
Full Name: Nethereum.JsonRpc.WebSocketClient.WebSocketClient
An instance of this can be be injected into a normal web3 object. Therefore it can be used in place of the default HTTP based client for all node based communication. It maintains an open web socket connection until it is disposed.
Creating and using a WebSocketClient
Retrieving the current block number:
using Nethereum.JsonRpc.WebSocketClient;
using Nethereum.Web3;
using Nethereum.Web3.Accounts.Managed;
using System;
using System.Threading.Tasks;
namespace NethereumSocketsAndStreaming
{
public class WS
{
public static async Task GetBlockNumberViaWebSocketAsync()
{
var account = new ManagedAccount("0x12890d2cce102216644c59daE5baed380d84830c", "password");
using(var clientws = new WebSocketClient("wss://rinkeby.infura.io/ws"))
{
var web3ws = new Web3(account, clientws);
var blockNumber = await web3ws.Eth.Blocks.GetBlockNumber.SendRequestAsync(); //task cancelled exception
Console.WriteLine("Block Number: " + blockNumber);
}
}
}
}
StreamingWebSocketClient
Related Nuget Packages:
- Nethereum.JsonRpc.WebSocketClient
- Nethereum.RPC.Reactive
- Nethereum.Parity.Reactive
- Nethereum.Web3
Full Name: Nethereum.JsonRpc.WebSocketStreamingClient
This is used to create subscriptions over a websocket connection. It keeps the connection open until disposed. Subscriptions are only active whilst the connection is open.
Subscriptions are available in these nuget packages: * Nethereum.RPC.Reactive * Nethereum.Parity.Reactive
Subscription Documentation
See subscription docs for more detail and examples.
Creating and using a StreamingWebSocketClient
Creating a NewBlockHeader subscription:
using Nethereum.JsonRpc.WebSocketStreamingClient;
using Nethereum.RPC.Reactive.Eth.Subscriptions;
using Newtonsoft.Json;
using System;
using System.Reactive.Linq;
using System.Threading.Tasks;
namespace Nethereum.WebSocketsStreamingTest
{
public class BlockHeader
{
public static async Task NewBlockHeader_With_Observable_Subscription()
{
using(var client = new StreamingWebSocketClient("wss://rinkeby.infura.io/ws"))
{
// create the subscription
// (it won't start receiving data until Subscribe is called)
var subscription = new EthNewBlockHeadersObservableSubscription(client);
// attach a handler for when the subscription is first created (optional)
// this will occur once after Subscribe has been called
subscription.GetSubscribeResponseAsObservable().Subscribe(subscriptionId =>
Console.WriteLine("Block Header subscription Id: " + subscriptionId));
DateTime? lastBlockNotification = null;
double secondsSinceLastBlock = 0;
// attach a handler for each block
// put your logic here
subscription.GetSubscriptionDataResponsesAsObservable().Subscribe(block =>
{
secondsSinceLastBlock = (lastBlockNotification == null) ? 0 : (int)DateTime.Now.Subtract(lastBlockNotification.Value).TotalSeconds;
lastBlockNotification = DateTime.Now;
var utcTimestamp = DateTimeOffset.FromUnixTimeSeconds((long)block.Timestamp.Value);
Console.WriteLine($"New Block. Number: {block.Number.Value}, Timestamp UTC: {JsonConvert.SerializeObject(utcTimestamp)}, Seconds since last block received: {secondsSinceLastBlock} ");
});
bool subscribed = true;
// handle unsubscription
// optional - but may be important depending on your use case
subscription.GetUnsubscribeResponseAsObservable().Subscribe(response =>
{
subscribed = false;
Console.WriteLine("Block Header unsubscribe result: " + response);
});
// open the websocket connection
await client.StartAsync();
// start the subscription
// this will only block long enough to register the subscription with the client
// once running - it won't block whilst waiting for blocks
// blocks will be delivered to our handler on another thread
await subscription.SubscribeAsync();
// run for a minute before unsubscribing
await Task.Delay(TimeSpan.FromMinutes(1));
// unsubscribe
await subscription.UnsubscribeAsync();
//allow time to unsubscribe
while (subscribed) await Task.Delay(TimeSpan.FromSeconds(1));
}
}
}
}