signalrAan de slag met signalr


Opmerkingen

Deze sectie geeft een overzicht van wat signalr is en waarom een ontwikkelaar het misschien wil gebruiken.

Het moet ook alle grote onderwerpen binnen signalr vermelden en een link naar de gerelateerde onderwerpen bevatten. Aangezien de documentatie voor signalr nieuw is, moet u mogelijk eerste versies van die gerelateerde onderwerpen maken.

versies

Versie Publicatiedatum
2.2.1 2016/07/13
2.2.0 2014/12/11
2.1.2 2014/09/09
2.1.1 2014/07/22
2.1.0 2014/05/21
2.0.3 2014/03/25
2.0.2 2014/01/22
2.0.1 2013/10/22
2.0.0 2013/08/29
1.2.2 2014/08/18
1.2.1 2014/02/10
1.2.0 2013/12/11
1.1.4 2013/10/22
1.1.3 2013/07/31
1.1.2 2013/05/24
1.1.1 2013/05/16
1.1.0 2013/05/11

Aan de slag

IIS / .NET-versie Vereisten : zie hier

SignaalR 2+

  1. Installeer het NuGet-pakket Microsoft.AspNet.SignalR (dit is de hele SignalR-oplossing) en u wordt gevraagd om afhankelijkheden voor andere pakketten te installeren. Accepteer de voorwaarden en installeer ze ook.

  2. Nu we de .dlls en clientscripts hebben die nodig zijn om onze eigen SignalR Hub te genereren, laten we er een maken. Klik op uw webproject, voeg een map met de naam Hubs of SignalR en voeg daarin een klasse NameOfYourChoosing Hub . Ik zal de mijne MessagingHub.cs noemen.

  3. We moeten afgeleid zijn van de Base Class Hub in onze SignalR-dll die we via NuGet hebben gedownload. De code ziet er als volgt uit:

    [HubName("messagingHub")]
    public class MessagingHub : Hub
    {
        //empty hub class
    }
     

    En in onze Startup.cs-klasse kunnen we de IAppBuilder weten dat we SignalR gaan gebruiken.

    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.MapSignalR();
            ConfigureAuth(app);
        }
    }
     
  4. Om naar onze hubcode op de client te verwijzen, moeten we 2 scripts importeren / verwijzen (afgezien van de voor de hand liggende jQuery-referentie). Het hoofdbestand jQuery.signalR-version.js en het gegenereerde hubs.js bestand dat SignalR specifiek voor onze hub genereert. Deze bronnen kunnen er zo uitzien:

    // script tag src="/YourAppPath/scripts/jquery-1.6.4.js"
    // script tag src="/YourAppPath/scripts/jquery.signalR-2.2.0.js"
    // script tag src="/YourAppPath/signalr/hubs"
     
  5. Aangezien JavaScript van SignalR bovenop jQuery is gebouwd (vereist> = v1.6.4), moet de code voor het verbinden en loskoppelen van de hub tamelijk triviaal zijn. Hier is het in al zijn glorie (verpakt in een IIFE):

    $(function() {
        //notice the camel casing of our hub name corresponding to the [HubName()] attribute on the server
        var connection = $.connection.messagingHub;
    
        $.connection.hub.start().done(function () {
            alert("Connection Successful!");
        }).fail(function (reason) {
            console.log("SignalR connection failed: " + reason);
        });
    });
     
  6. Vanaf nu moeten we de app kunnen uitvoeren en een verbinding kunnen maken met de SignalR-hub.

SignalR gebruiken met Web API en JavaScript Web App, met CORS-ondersteuning.

Doel: gebruik SignalR voor meldingen tussen de web-API en de op TypeScript / JavaScript gebaseerde web-app, waarbij de web-API en de web-app in een ander domein worden gehost.

SignalR en CORS inschakelen op Web API: maak een standaard Web API-project en installeer de volgende NuGet-pakketten:

  • Microsoft.Owin.Cors
  • Microsoft.AspNet.WebApi.Cors
  • Microsoft.AspNet.WebApi.Owin
  • Microsoft.AspNet.SignalR.Core

Daarna kun je de Global.asax en in plaats daarvan een OWIN Startup-klasse toevoegen.

using System.Web.Http;
using System.Web.Http.Cors;
using Microsoft.Owin;
using Owin;

[assembly: OwinStartup(typeof(WebAPI.Startup), "Configuration")]
namespace WebAPI
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
        
            var httpConfig = new HttpConfiguration();
            
            //change this configuration as you want.
            var cors = new EnableCorsAttribute("http://localhost:9000", "*", "*"); 
            httpConfig.EnableCors(cors);

            SignalRConfig.Register(app, cors);

            WebApiConfig.Register(httpConfig);

            app.UseWebApi(httpConfig);
        }
    }
}
 

Maak de klasse SignalRConfig als volgt:

using System.Linq;
using System.Threading.Tasks;
using System.Web.Cors;
using System.Web.Http.Cors;
using Microsoft.Owin.Cors;
using Owin;

namespace WebAPI
{
    public static class SignalRConfig
    {
        public static void Register(IAppBuilder app, EnableCorsAttribute cors)
        {

            app.Map("/signalr", map =>
            {
                var corsOption = new CorsOptions
                {
                    PolicyProvider = new CorsPolicyProvider
                    {
                        PolicyResolver = context =>
                        {
                            var policy = new CorsPolicy { AllowAnyHeader = true, AllowAnyMethod = true, SupportsCredentials = true };

                            // Only allow CORS requests from the trusted domains.
                            cors.Origins.ToList().ForEach(o => policy.Origins.Add(o));

                            return Task.FromResult(policy);
                        }
                    }
                };
                map.UseCors(corsOption).RunSignalR();
            });
        }
    }
}
 

Tot nu toe hebben we zojuist SignalR met CORS aan serverzijde ingeschakeld. Laten we nu eens kijken hoe u gebeurtenissen vanaf de server kunt publiceren. Hiervoor hebben we een Hub :

public class NotificationHub:Hub
{
    //this can be in Web API or in any other class library that is referred from Web API.
}
 

Nu eindelijk een code om de verandering daadwerkelijk uit te zenden:

public class SuperHeroController : ApiController
{
    [HttpGet]
    public string RevealAlterEgo(string id)
    {
        var alterEgo = $"The alter ego of {id} is not known.";
        var superHero = _superHeroes.SingleOrDefault(sh => sh.Name.Equals(id));
        if (superHero != null)
        {
            alterEgo = superHero.AlterEgo;
            
            /*This is how you broadcast the change. 
             *For simplicity, in this example, the broadcast is done from a Controller, 
             *but, this can be done from any other associated class library having access to NotificationHub.
             */
            var notificationHubContext = GlobalHost.ConnectionManager.GetHubContext<NotificationHub>();
            if (notificationHubContext != null)
            {
                var changeData = new { changeType = "Critical", whatHappened = $"Alter ego of {id} is revealed." };

                //somethingChanged is an arbitrary method name.
                //however, same method name is also needs to be used in client.
                notificationHubContext.Clients.All.somethingChanged(changeData);
            }
        }
        return alterEgo;
    }
}
 

Tot dusverre hebben we de server klaargemaakt. Voor de client hebben we jQuery en signalr pakket nodig. U kunt beide met jspm installeren. Installeer indien nodig de typen voor beide.

We zullen de standaard gegenereerde JavaScript-proxy niet gebruiken. We zullen liever een heel eenvoudige klasse maken om de SignalR-communicatie af te handelen.

/**
 * This is created based on this gist: https://gist.github.com/donald-slagle/bf0673b3c188f3a2559c.
 * As we are crreating our own SignalR proxy, 
 * we don't need to get the auto generated proxy using `signalr/hubs` link.
 */
export class SignalRClient {

    public connection = undefined;
    private running: boolean = false;

    public getOrCreateHub(hubName: string) {
        hubName = hubName.toLowerCase();
        if (!this.connection) {
            this.connection = jQuery.hubConnection("https://localhost:44378");
        }

        if (!this.connection.proxies[hubName]) {
            this.connection.createHubProxy(hubName);
        }

        return this.connection.proxies[hubName];
    }

    public registerCallback(hubName: string, methodName: string, callback: (...msg: any[]) => void,
        startIfNotStarted: boolean = true) {

        var hubProxy = this.getOrCreateHub(hubName);
        hubProxy.on(methodName, callback);

        //Note: Unlike C# clients, for JavaScript clients, 
        //      at least one callback needs to be registered, 
        //      prior to start the connection.
        if (!this.running && startIfNotStarted)
            this.start();
    }

    start() {
        const self = this;
        if (!self.running) {
            self.connection.start()
                .done(function () {
                    console.log('Now connected, connection Id=' + self.connection.id);
                    self.running = true;
                })
                .fail(function () {
                    console.log('Could not connect');
                });
        }
    }
}
 

Gebruik ten slotte deze klasse om als volgt naar veranderende uitzendingen te luisteren:

/**
 * Though the example contains Aurelia codes, 
 * the main part of SignalR communication is without any Aurelia dependency.
 */
import {autoinject, bindable} from "aurelia-framework";
import {SignalRClient} from "./SignalRClient";

@autoinject
export class SomeClass{
    
    //Instantiate SignalRClient.
    constructor(private signalRClient: SignalRClient) {
    }

    attached() {
        //To register callback you can use lambda expression...
        this.signalRClient.registerCallback("notificationHub", "somethingChanged", (data) => {
            console.log("Notified in VM via signalr.", data);
        });
        
        //... or function name.
        this.signalRClient.registerCallback("notificationHub", "somethingChanged", this.somethingChanged);
    }

    somethingChanged(data) {
        console.log("Notified in VM, somethingChanged, via signalr.", data);
    }
}