Click here to Skip to main content
15,884,298 members
Articles / Web Development / HTML

ASP.NET CORE 2.0 Uses SignalR Technology

Rate me:
Please Sign up or sign in to vote.
4.65/5 (9 votes)
28 Sep 2017CPOL2 min read 19.4K   285   10   9
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.

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, such as 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 a preview version, so NuGet cannot find the SignalR package, would like to add a reference we have to go to MyGet look up. Since the use of MyGet, it is necessary to add NuGet source for the project.

Add the NuGet Source

In the program root directory, to create a new file for the NuGet.Config contents are as follows:

XML
<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <packageSources>
        <clear/>
            <add key="aspnetcidev" 
             value="https://dotnet.myget.org/F/aspnetcore-ci-dev/api/v3/index.json"/>
            <add key="api.nuget.org" value="https://api.nuget.org/v3/index.json"/>
    </packageSources>
</configuration>

Edit the Project File csproj

Add the references to the two packages mentioned above:

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

I am using the current highest 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, also modify the revised version number here: Microsoft.AspNetCore.All 2.0.0-preview3-26040.

Of course, you can also use dotnet cli to add the package reference:

dotnet add package Microsoft.AspNetCore.SignalR --version 1.0.1-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 to Startup class in the ConfigureServices method to add the following code:

C#
public void ConfigureServices(IServiceCollection services)
{
    services.AddSignalR();
}

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

C#
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseStaticFiles();
    app.UseSignalR(routes =>
    {
        routes.MapHub<Chat>("hubs");
    });
}

Add a HUB Class

C#
public class Chat : Hub
{
    public override async Task OnConnectedAsync()
    {
        await Clients.All.InvokeAsync("Send", $"{Context.ConnectionId} joined");
    }

    public override async Task OnDisconnectedAsync(Exception ex)
    {
        await Clients.All.InvokeAsync("Send", $"{Context.ConnectionId} left");
    }

    public Task Send(string message)
    {
        return Clients.All.InvokeAsync("Send", $"{Context.ConnectionId}: {message}");
    }

    public Task SendToGroup(string groupName, string message)
    {
        return Clients.Group(groupName).InvokeAsync
                ("Send", $"{Context.ConnectionId}@{groupName}: {message}");
    }

    public async Task JoinGroup(string groupName)
    {
        await Groups.AddAsync(Context.ConnectionId, groupName);

        await Clients.Group(groupName).InvokeAsync
                ("Send", $"{Context.ConnectionId} joined {groupName}");
    }

    public async Task LeaveGroup(string groupName)
    {
        await Groups.RemoveAsync(Context.ConnectionId, groupName);

        await Clients.Group(groupName).InvokeAsync
                ("Send", $"{Context.ConnectionId} left {groupName}");
    }

    public Task Echo(string message)
    {
        return Clients.Client(Context.ConnectionId).InvokeAsync
               ("Send", $"{Context.ConnectionId}: {message}");
    }
}

Client Support

In the wwwroot directory to create a chat.html called HTML static file, reads as follows:

HTML
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    <h1 id="head1"></h1>
    <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>


    <h4>To Everybody</h4>
    <form class="form-inline">
        <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>
    </form>

    <h4>To Me</h4>
    <form class="form-inline">
        <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>
    </form>

    <h4>Private Message</h4>
    <form class="form-inline">
        <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>
    </form>

    <ul id="message-list"></ul>
</body>
</html>
<script src="signalr-client.js"></script>
<script src="utils.js"></script>
<script>
var isConnected = false;
function invoke(connection, method, ...args) {
    if (!isConnected) {
        return;
    }
    var argsArray = Array.prototype.slice.call(arguments);
    connection.invoke.apply(connection, argsArray.slice(1))
            .then(result => {
                console.log("invocation completed successfully: " + 
                           (result === null ? '(null)' : result));

                if (result) {
                    addLine('message-list', result);
                }
            })
            .catch(err => {
                addLine('message-list', err, 'red');
            });
}

function getText(id) {
    return document.getElementById(id).value;
}

let transportType = signalR.TransportType[getParameterByName('transport')] || 
                    signalR.TransportType.WebSockets;

document.getElementById('head1').innerHTML = signalR.TransportType[transportType];

let connectButton = document.getElementById('connect');
let disconnectButton = document.getElementById('disconnect');
disconnectButton.disabled = true;
var connection;

click('connect', event => {
    connectButton.disabled = true;
    disconnectButton.disabled = false;
    let http = new signalR.HttpConnection(`http://${document.location.host}/hubs`, 
               { transport: transportType });
    connection = new signalR.HubConnection(http);
    connection.on('Send', msg => {
        addLine('message-list', msg);
    });

    connection.onClosed = e => {
        if (e) {
            addLine('message-list', 'Connection closed with error: ' + e, 'red');
        }
        else {
            addLine('message-list', 'Disconnected', 'green');
        }
    }

    connection.start()
        .then(() => {
            isConnected = true;
            addLine('message-list', 'Connected successfully', 'green');
        })
        .catch(err => {
            addLine('message-list', err, 'red');
        });
});

click('disconnect', event => {
    connectButton.disabled = false;
    disconnectButton.disabled = true;
    connection.stop()
        .then(() => {
            isConnected = false;
        });
});

click('broadcast', event => {
    let data = getText('message-text');
    invoke(connection, 'Send', data);
});

click('join-group', event => {
    let groupName = getText('message-text');
    invoke(connection, 'JoinGroup', groupName);
});

click('leave-group', event => {
    let groupName = getText('message-text');
    invoke(connection, 'LeaveGroup', groupName);
});

click('groupmsg', event => {
    let groupName = getText('target');
    let message = getText('private-message-text');
    invoke(connection, 'SendToGroup', groupName, message);
});

click('send', event => {
    let data = getText('me-message-text');
    invoke(connection, 'Echo', data);
});

</script>

It is worth noting that you may find that there is no signalr-client.js in this document, how does it come, there are two ways:

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

The second kind of relatively simple way is through Npm which can be obtained online:

npm install signalr-client --registry https://dotnet.myget.org/f/aspnetcore-ci-dev/npm/

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead
Canada Canada
I am Rebaï Hamida, Microsoft MVP in Visual Studio and Development Technologies.
I'm a software architect and developer who like to build open source projects, writing articles, learning and teaching best practices. you can find out in my blog : http://hamidarebai.blogspot.com/

Innovative Software engineer : hands-on, competent software engineer, passionate and proficient C# developer, offering more than seven years of experience in the full software development lifecycle – from concept through delivery of next-generation applications and customized solutions, producing code to a consistently high standard and testing software across a variety of platforms.
Expert in advanced development methodologies, tools and processes contributing to the design and roll-out of cutting-edge software applications.
Known for excellent troubleshooting skills – able to analyze code and engineer well-researched, cost-effective and responsive solutions.


Success is only a consequence of a continuous work and remarkable intelligence.
I believe that I have to make a change in my country, I can’t live without leaving my footprint.

Comments and Discussions

 
QuestionGood article. On running the code, while clicking on Connect button, I am getting an error 1006. How come its possible? Pin
Rahul1985b12-Feb-18 18:45
Rahul1985b12-Feb-18 18:45 
AnswerRe: Good article. On running the code, while clicking on Connect button, I am getting an error 1006. How come its possible? Pin
KWHJ_JWHK15-Feb-18 11:33
KWHJ_JWHK15-Feb-18 11:33 
GeneralMy vote of 1 Pin
KWHJ_JWHK12-Jan-18 6:32
KWHJ_JWHK12-Jan-18 6:32 
SuggestionSuggestion to improve your work ... Pin
KWHJ_JWHK12-Jan-18 5:01
KWHJ_JWHK12-Jan-18 5:01 
GeneralRe: Suggestion to improve your work ... Pin
didourebai13-Jan-18 8:32
professionaldidourebai13-Jan-18 8:32 
Question[My vote of 1] What kind of article is this? Vote 1 Pin
hikaru0073-Oct-17 20:12
professionalhikaru0073-Oct-17 20:12 
AnswerRe: [My vote of 1] What kind of article is this? Vote 1 Pin
didourebai4-Oct-17 0:11
professionaldidourebai4-Oct-17 0:11 
GeneralRe: [My vote of 1] What kind of article is this? Vote 1 Pin
didourebai4-Oct-17 0:14
professionaldidourebai4-Oct-17 0:14 
GeneralMy vote of 5 Pin
san2debug2-Oct-17 17:24
professionalsan2debug2-Oct-17 17:24 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.