ASP.NET Core 2.0 Uses SignalR Technology

Introduction

The ASP.NET Core 1.x.x release does not include SignalR technology and development plans. Time has passed quickly. Microsoft has released a preview version of. NET Core 2.0 Preview 2. Not far from the official version, the above also mentioned in the ASP.NET Core 2.0 SignalR will be as important components and MVC and other frameworks released together. Its development team also fulfilled the commitment to use TypeScript to rewrite its JavaScript client, the server side will be close to the ASP.NET Core development, and will be integrated into the ASP.NET Core dependent injection framework.

Environment to build

To use SignalR in ASP.NET Core 2.0, first reference Microsoft.AspNetCore.SignalR, Microsoft.AspNetCore.SignalR.Http two package packages.

At present, ASP.NET Core 2.0 and SignalR are also in preview versions. So, NuGet cannot find the SignalR package. If we would like to add a reference, we have to go to MyGet look up. Since we use the MyGet, it is necessary to add NuGet source for the project.

Add the NuGet source

In the program root directory, create a new file for the NuGet.Config content.

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <configuration>  
  3.     <packageSources>  
  4.         <clear/>  
  5.         <add key="aspnetcidev" value="https://dotnet.myget.org/F/aspnetcore-ci-dev/api/v3/index.json" />  
  6.         <add key="api.nuget.org" value="https://api.nuget.org/v3/index.json" /> </packageSources>  
  7. </configuration>  
Edit the project file csproj

Add the references to the two packages mentioned above:

  1. <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />  
  2. <PackageReference Include="Microsoft.AspNetCore.SignalR" Version="1.0.0-alpha-final" />  
  3. <PackageReference Include="Microsoft.AspNetCore.SignalR.Http" Version="0.0.1-alpha" />  

I am using the current highest vesion in this example. Of course, the version number is likely to change every day. The latest version of the SignalR is not compatible with the .NET Core SDK 2.0 Preview 1 by default. When creating the project Microsoft.AspNetCore.All, this package version, modify the revised version number: Microsoft.AspNetCore.All 1.0.0-alpha-final.

You can also use .NET CLI to add the package reference.

dotnet add package Microsoft.AspNetCore.SignalR --version 1.0.0-alpha-final --source https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json dotnet add package Microsoft.AspNetCore.SignalR.Http --version 0.0.1-alpha --source https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json

Add the configuration code.

We need a Startup class in the ConfigureServices method to add the following code:

  1. public void ConfigureServices(IServiceCollection services) {  
  2.     services.AddSignalR();  
  3. }  

Add the following code to the Configure method in the Startup class:

  1. public void Configure(IApplicationBuilder app, IHostingEnvironment env) {  
  2.     app.UseStaticFiles();  
  3.     app.UseSignalR(routes => {  
  4.         routes.MapHub < Chat > ("hubs");  
  5.     });  
  6. }  
Add a HUB class.

  1. public class Chat: Hub {  
  2.     public override async Task OnConnectedAsync() {  
  3.         await Clients.All.InvokeAsync("Send", $ "{Context.ConnectionId} joined");  
  4.     }  
  5.     public override async Task OnDisconnectedAsync(Exception ex) {  
  6.         await Clients.All.InvokeAsync("Send", $ "{Context.ConnectionId} left");  
  7.     }  
  8.     public Task Send(string message) {  
  9.         return Clients.All.InvokeAsync("Send", $ "{Context.ConnectionId}: {message}");  
  10.     }  
  11.     public Task SendToGroup(string groupName, string message) {  
  12.         return Clients.Group(groupName).InvokeAsync("Send", $ "{Context.ConnectionId}@{groupName}: {message}");  
  13.     }  
  14.     public async Task JoinGroup(string groupName) {  
  15.         await Groups.AddAsync(Context.ConnectionId, groupName);  
  16.         await Clients.Group(groupName).InvokeAsync("Send", $ "{Context.ConnectionId} joined {groupName}");  
  17.     }  
  18.     public async Task LeaveGroup(string groupName) {  
  19.         await Groups.RemoveAsync(Context.ConnectionId, groupName);  
  20.         await Clients.Group(groupName).InvokeAsync("Send", $ "{Context.ConnectionId} left {groupName}");  
  21.     }  
  22.     public Task Echo(string message) {  
  23.         return Clients.Client(Context.ConnectionId).InvokeAsync("Send", $ "{Context.ConnectionId}: {message}");  
  24.     }  
  25. }  
Client support

In the wwwroot directory, create a chat.html page called Html static file.

  1. <!DOCTYPE html>  
  2. <html>  
  3.   
  4. <head>  
  5.     <meta charset="utf-8" />  
  6.     <title></title>  
  7. </head>  
  8.   
  9. <body>  
  10.     <h1 id="head1"></h1>  
  11.     <div> <select id="formatType"> <option value="json">json</option> <option value="line">line</option> </select> <input type="button" id="connect" value="Connect" /> <input type="button" id="disconnect" value="Disconnect" /> </div>  
  12.     <h4>To Everybody</h4>  
  13.     <form class="form-inline">  
  14.         <div class="input-append"> <input type="text" id="message-text" placeholder="Type a message, name or group" /> <input type="button" id="broadcast" class="btn" value="Broadcast" /> <input type="button" id="broadcast-exceptme" class="btn" value="Broadcast (All Except Me)" /> <input type="button" id="join" class="btn" value="Enter Name" /> <input type="button" id="join-group" class="btn" value="Join Group" /> <input type="button" id="leave-group" class="btn" value="Leave Group" /> </div>  
  15.     </form>  
  16.     <h4>To Me</h4>  
  17.     <form class="form-inline">  
  18.         <div class="input-append"> <input type="text" id="me-message-text" placeholder="Type a message" /> <input type="button" id="send" class="btn" value="Send to me" /> </div>  
  19.     </form>  
  20.     <h4>Private Message</h4>  
  21.     <form class="form-inline">  
  22.         <div class="input-prepend input-append"> <input type="text" name="private-message" id="private-message-text" placeholder="Type a message" /> <input type="text" name="user" id="target" placeholder="Type a user or group name" /> <input type="button" id="privatemsg" class="btn" value="Send to user" /> <input type="button" id="groupmsg" class="btn" value="Send to group" /> </div>  
  23.     </form>  
  24.     <ul id="message-list"></ul>  
  25. </body>  
  26.   
  27. </html>  
  28. <script src="signalr-client.js"></script>  
  29. <script src="utils.js"></script>  
  30. <script>  
  31.     var isConnected = false;  
  32.   
  33.     function invoke(connection, method, ...args) {  
  34.         if (!isConnected) {  
  35.             return;  
  36.         }  
  37.         var argsArray = Array.prototype.slice.call(arguments);  
  38.         connection.invoke.apply(connection, argsArray.slice(1)).then(result => {  
  39.             console.log("invocation completed successfully: " + (result === null ? '(null)' : result));  
  40.             if (result) {  
  41.                 addLine('message-list', result);  
  42.             }  
  43.         }).catch(err => {  
  44.             addLine('message-list', err, 'red');  
  45.         });  
  46.     }  
  47.   
  48.     function getText(id) {  
  49.         return document.getElementById(id).value;  
  50.     }  
  51.     let transportType = signalR.TransportType[getParameterByName('transport')] || signalR.TransportType.WebSockets;  
  52.     document.getElementById('head1').innerHTML = signalR.TransportType[transportType];  
  53.     let connectButton = document.getElementById('connect');  
  54.     let disconnectButton = document.getElementById('disconnect');  
  55.     disconnectButton.disabled = true;  
  56.     var connection;  
  57.     click('connect', event => {  
  58.         connectButton.disabled = true;  
  59.         disconnectButton.disabled = false;  
  60.         let http = new signalR.HttpConnection(`http://${document.location.host}/hubs`, {  
  61.             transport: transportType  
  62.         });  
  63.         connection = new signalR.HubConnection(http);  
  64.         connection.on('Send', msg => {  
  65.             addLine('message-list', msg);  
  66.         });  
  67.         connection.onClosed = e => {  
  68.             if (e) {  
  69.                 addLine('message-list''Connection closed with error: ' + e, 'red');  
  70.             } else {  
  71.                 addLine('message-list''Disconnected''green');  
  72.             }  
  73.         }  
  74.         connection.start().then(() => {  
  75.             isConnected = true;  
  76.             addLine('message-list''Connected successfully''green');  
  77.         }).catch(err => {  
  78.             addLine('message-list', err, 'red');  
  79.         });  
  80.     });  
  81.     click('disconnect', event => {  
  82.         connectButton.disabled = false;  
  83.         disconnectButton.disabled = true;  
  84.         connection.stop().then(() => {  
  85.             isConnected = false;  
  86.         });  
  87.     });  
  88.     click('broadcast', event => {  
  89.         let data = getText('message-text');  
  90.         invoke(connection, 'Send', data);  
  91.     });  
  92.     click('join-group', event => {  
  93.         let groupName = getText('message-text');  
  94.         invoke(connection, 'JoinGroup', groupName);  
  95.     });  
  96.     click('leave-group', event => {  
  97.         let groupName = getText('message-text');  
  98.         invoke(connection, 'LeaveGroup', groupName);  
  99.     });  
  100.     click('groupmsg', event => {  
  101.         let groupName = getText('target');  
  102.         let message = getText('private-message-text');  
  103.         invoke(connection, 'SendToGroup', groupName, message);  
  104.     });  
  105.     click('send', event => {  
  106.         let data = getText('me-message-text');  
  107.         invoke(connection, 'Echo', data);  
  108.     });  
  109. </script>  

It is worth noting that there is no signalr-client.js in this document. There are two ways to bring it in the project.

The first way is to download the SignalR source code, find the Client-TS project, and compile the TypeScript.

The second way is relatively simple, i.e., through NPM.

npm install signalr-client --registry

The output

 
 
 
And then