Newly written SignalR with .Net Core 2.0 and TypeScript

signalr

Update 02/15/2018 – Please note that this is a pre-release version and it is not production ready yet. https://github.com/aspnet/SignalR/issues/429 for more discussion.

Whenever we want to implement real-time web functionality in .Net then first thing comes to our mind is SignalR.

What is SignalR?

ASP.NET SignalR is a library for ASP.NET developers that makes developing real-time web functionality easy. SignalR allows bi-directional communication between server and client. Servers can now push content to connected clients instantly as it becomes available. SignalR supports Web Sockets, and falls back to other compatible techniques for older browsers. SignalR includes APIs for connection management (for instance, connect and disconnect events), grouping connections, and authorization.

So basically SignalR can be used for pub-sub, Client-Server applications.

For example, we can implement chat with the use of SignalR. For this, client first subscribes to the Hub and once it is subscribed, Hub pushes the updates as soon as the updates are available.

Microsoft has announced .net core 2.0 in last August which did not have support for SignalR but recently SignalR has been rewritten to support .Net Core. The new SignalR is simpler, more reliable, and easier to use.

Important Note:

Please note that new SignalR is not compatible with previous versions of SignalR. It means that we cannot use the old server with the new clients or the old clients with the new server.

TypeScript Client

Till now the SignalR client was mostly depended upon the jQuery but with the newer version of SignalR has Javascript client which is written in TypeScript. It can be used from Node.js as well.

Let us create a sample client which we will use to invoke methods from the server(Sample of Hub server can be found at the end of the current post)

For Installation:

npm install @aspnet/signalr-client

Setup:

First of all, you need to add below dependencies in package.json file to use the client in Node.js application:

"dependencies": {
  "atob": "^2.0.3",
  "btoa": "^1.1.2",
  "eventsource": "^1.0.5",
  "msgpack5": "^3.5.1",
  "websocket": "^1.0.24",
  "xmlhttprequest": "^1.8.0"
},

For Example, you want to make an application which reads stock rates as soon as the market is opened then first we will create a new hub connection in stocks.ts typescript file:

let hubConnection = new signalR.HubConnection("http://localhost:8080/stocks");
Then we will write streamStocks method which will collect the stock data by calling StreamStocks method of the hub:
function streamStocks (): void {
     hubConnection.stream("StreamStocks").subscribe({
      next: (stock : any) => {
            console.log(stock);
     },
    error: () => {},
       complete: () => {}
     });
}
Then we will invoke the method streamStocks if the market is open and will invoke OpenMarket method if the market is not opened yet:
hubConnection.start().then(() => {
   hubConnection.invoke("GetMarketState").then(function (state : string): void {
   if (state === "Open") {
          streamStocks();
    } else {
            hubConnection.invoke("OpenMarket");
      }
  });
}).catch(err => {
console.log(err);
});
We can subscribe to marketOpened event which will then call streamStocks once the market is opened as below:
hubConnection.on("marketOpened", function(): void {
streamStocks();
});

Streaming

It is now possible to stream data from the server to the client. Unlike a regular Hub method invocation, streaming means the server is able to send results to the client before the invocation completes.

Not more than one Hub per connection

New SignalR does not support multiple hubs per connection also it is now not required to subscribe Hub methods before the connection starts.

SignalR Server example

As we have created the client, now let us create the hub.

First of all, create an empty web application from Visual Studio 2017 templates:

core3

Then we need to add SignalR reference which you can add from Package console manager as shown below:

Install-Package Microsoft.AspNetCore.SignalR -Pre

which will add the SignalR reference into the project as below:

<ItemGroup>
   <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
   <PackageReference Include="Microsoft.AspNetCore.SignalR" Version="1.0.0-alpha2-final" />
</ItemGroup>

Now create a hub class for Stocks which can communicate with all subscribed clients

using Microsoft.AspNetCore.SignalR; 

namespace SignalRApplication 
{   
public class StockHub: Hub   
{ 
private readonly Stock _stock; 
public StockHub(Stock stock) 
{ _stock = stock; } 

////To take the advantage of streaming you need to create a hub method that returns either a ReadableChannel<T> or an IObservable<T> as shown in above code 
public IObservable<Stock> StreamStocks() 
{ 
return _stock.StreamStocks(); 
} 

public string GetMarketState() 
{ 
return _stock.MarketState.ToString(); 
}     

public async Task OpenMarket() 
{ 
await _stock.OpenMarket(); 
} 

public async Task CloseMarket() 
{ 
await _stock.CloseMarket(); 
}  
 } 
}

Hub has the capability to connect with all the clients which have been subscribed to the hub

Note: Here Stock service contains all important implementation of Open\Close market methods but we will not go into the details of implementation in the current post.

After adding a Hub class you need to configure the server to pass requests sent to the stock hub to SignalR:

public class Startup { 
public void ConfigureServices(IServiceCollection services) 
{ 
services.AddSignalR(); 
services.AddScoped<StockHub>(); 
services.AddSingleton<Stock>(); 
} 

public void Configure(IApplicationBuilder app) 
{ 
app.UseFileServer(); 
app.UseSignalR(routes => { routes.MapHub<StockHub>("stocks"); }); 
} 
}

Once the set up of the server is done, you can invoke hub methods from the client(which we have created in the starting of this post) and receive invocations from the server.

So once we run the client:

  • Connection with the hub will be started and GetMarketState will be called which will return the current state of market
  • If the market state is opened then StreamStocks will be called which will return the stock data in stream. To take the advantage of streaming you need to create a hub method that returns either a ReadableChannel<T> or an IObservable<T> as shown in above code
  • If the market is not opened, market will be first opened and then StreamStocks will be called

Whenever we run the application, it will get the real time stock data as below:

signalr2

Code sample credit – https://github.com/aspnet/signalr-samples

Hope it helps.

Advertisement

9 thoughts on “Newly written SignalR with .Net Core 2.0 and TypeScript

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s