How to add asynchronous, real-time data stream from a cross-platform .NET back-end to your React web app with much less effort. If you ever have to deal with asynchronous data streams, you probably have used or at least heard of , a library for reactive which offers powerful APIs to transform data streams into observable sequences that can be subscribed to and acted upon. But what sets it apart from the regular event-driven approach is the capability to compose new data streams out of multiple of other observable sequences, which you can combine, filter, or transform with great flexibility. ReactiveX programming I will demonstrate how you can leverage this and my own library to make an asynchronous real-time web application fairly trivial to implement. Here is the output of what we will be building: dotNetify-React It is a live chart on a web browser, fed by an asynchronous data stream that is itself composed of two different data streams; one for the sine wave signal and the other its amplitude. The following steps use the boilerplate from Facebook to generate the web app, and to run the back-end. You will need to install them first. create-react-app .NET Core SDK If you just want to pull the source code, go to Github . There is also a version that runs on Visual Studio 2017 at . dotnetify-react-demo dotnetify-react-demo-vs2017 Front-End We will start by creating the app shell and installing the required libraries: create-react-app livechartcd livechartnpm install dotnetify --savenpm install chart.js@1.1.1 --savenpm install react-chartjs@0.8.0 --savenpm install concurrently --save-dev (I keep to an older version of the chart library because the APIs have changed since and I‘m not familiar with them yet.) Add the component that will render the chart: /src/LiveChart.jsx import React from 'react';import dotnetify from 'dotnetify';import { Bar } from 'react-chartjs'; export default class LiveChart extends React.Component {constructor(props) {super(props);dotnetify.react.connect("LiveChart", this);this.state = {}; this.chartData = { labels: Array(10).fill(""), datasets: \[{ data: Array(10), fillColor: 'rgba(75, 192, 192, 0.2)', strokeColor: 'rgba(75, 192, 192, 1)' }\] }; this.chartOptions = { responsive: true, scaleOverride: true, scaleSteps: 5, scaleStepWidth: 10 }; this.updateChart = value => { this.chartData.datasets\[0\].data.shift(); this.chartData.datasets\[0\].data.push(value); }; }render() {return (<Bar data={this.chartData} options={this.chartOptions}>{this.updateChart(this.state.NextValue)}</Bar>);}} This component will initially render a bar chart component from with an empty data set. As soon as the connection to the back-end through occurs, the component will be receiving real-time update to , which in turn causes the chart to re-render with the new data set value. react-chartjs dotNetify this.state.NextValue Next, replace the default to render our component: /src/App.js import React, { Component } from 'react';import LiveChart from './LiveChart'; export default class App extends Component {render() {return <LiveChart />}} Back-End With the front-end in place, we now add the .NET Core back-end piece. Start by creating a default ASP.NET Core web project and installing the required packages: dotnet new webdotnet add package DotNetify.SignalR --version 2.1.0-predotnet add package System.Reactivedotnet restore Open and add the following line to redirect requests that are unhandled by the Node dev server to the .NET Core server: package.json "proxy": "http://localhost:5000/", Still in , modify the line that calls the to use the library to start both Node and .NET Core server: package.json react-scripts concurrently "start": "concurrently \"react-scripts start\" \"dotnet run\" --kill-others", Next, add the class that will provide the real-time update to the front-end component: LiveChart.cs using System;using System.Reactive.Linq; namespace livechart{public class LiveChart : DotNetify.BaseVM{private IDisposable _subscription;public int NextValue { get; set; } public LiveChart() { var sine = Observable .Interval(TimeSpan.FromMilliseconds(100)) .Select(t => Math.Sin(2 \* Math.PI \* .06 \* t)); var amp = Observable .Interval(TimeSpan.FromMilliseconds(100)) .Select(a => a % 50 + 1); \_subscription = Observable .Zip(sine, amp, (s, a) => (int) Math.Abs( s \* a)) .Subscribe(value => { NextValue = value; Changed(nameof(NextValue)); PushUpdates(); }); } public override void Dispose() => \_subscription.Dispose(); }} The idea behind this class is to produce a data stream that’s composed of two other streams: one for the sine wave signal, the other an iteration of numbers to make a fluctuating amplitude. To create the streams, we use the to emit a sequence of integers in a time interval, which is then further projected into the desired sequence. The two streams are then combined with into a single stream, which is subscribed to by our class instance. Rx API Observable.Interval Observable.Zip When new data becomes available, we use the API and to send the data to the front-end component to update its local state. The actual communication is done through , which will use when available. But we don’t have to worry about it, since it’s already abstracted away. dotNetify Changed PushUpdates SignalR WebSocket Next, configure and in the dotNetify SignalR Startup.cs: using Microsoft.AspNetCore.Builder;using Microsoft.AspNetCore.Hosting;using Microsoft.AspNetCore.Http;using Microsoft.Extensions.DependencyInjection;using DotNetify; namespace livechart{public class Startup{public void ConfigureServices(IServiceCollection services){services.AddMemoryCache();services.AddSignalR();services.AddDotNetify();}public void Configure(IApplicationBuilder app){app.UseWebSockets();app.UseSignalR();app.UseDotNetify();app.Run(async (context) =>{await context.Response.WriteAsync("LiveChart server");});}}} Finally, build and run the application: dotnet buildnpm start Summary And, that’s it. An asynchronous real-time web app that you can quickly build in minutes. Although somewhat a contrived example, I hope it still serves to illustrate how powerful this technique can be. In a real-world scenario, the web client could be waiting for multiple back-end microservices whose asynchronous outputs need to be chained together to produce the final result. The usage of and combo will significantly reduce the code complexity and save you time and effort. ReactiveX dotNetify