web-dev-qa-db-fra.com

Impossible d’établir une connexion avec le hub principal de Signalr avec Angular 5 client

J'ai une API Web .Net Core 2.0 C # exécutant un hub SignalR Core. Je ne peux même pas démarrer () mon hubConnection d'angular (5.0.1) en recevant cette erreur:

OPTIONS https: // localhost: 44301/hubs/sample 405 (méthode non autorisée)

Erreur: Impossible de démarrer la connexion. Erreur: méthode non autorisée

Erreur lors de l'établissement de la connexion :(

Échec du chargement de XHR: OPTIONS " https: // localhost: 44301/hubs/sample ".

HttpError: Méthode non autorisée at XMLHttpRequest.xhr.onload [as __zone_symbol__ON_PROPERTYload] (webpack-internal: ///../../../@aspnet/signalr-client/dist/src/HttpClient.js: 30: 28) à XMLHttpRequest.wrapFn (webpack-internal: ///../../../../zone.js/dist/zone.js: 1166: 39) sur ZoneDelegate.invokeTask (webpack-internal: ///../../../../zone.js/dist/zone.js: 425: 31) sur Object.onInvokeTask (webpack-internal: ///../../../core/esm5/core.js: 4816: 33) sur ZoneDelegate.invokeTask (webpack-internal: ///../../../../zone.js/dist/zone.js: 424: 36) sur Zone.runTask (webpack-internal: ///../../../../zone.js/dist/zone.js: 192: 47) sur ZoneTask.invokeTask [as invoke] (webpack-internal: ///../../../../zone.js/dist/zone.js: 499: 34) à invokeTask (webpack-internal: ///../../../../zone.js/dist/zone.js: 1540: 14) at XMLHttpRequest.globalZoneAwareCallback (webpack-internal: ///../../../../zone.js/dist/zone.js: 1566: 17)

Je me bats même pour résoudre ce problème, même avec l'aide d'un violoniste je ne suis pas capable de le résoudre. Cela ne semble pas être un problème avec mon Api car la console Kestrel imprime que la demande au concentrateur est arrivée, mais n'imprime aucune erreur. Et je peux obtenir, mettre et POST à mes contrôleurs sans problème.

Voici ma configuration StartUp.cs (j'ai omis du code non pertinent pour des raisons de concision)

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(options =>
    {
        options.AddPolicy(
            "CorsPolicy",
            builder =>
                builder
                .AllowAnyOrigin()
                .AllowAnyHeader()
                .AllowAnyMethod()
                .AllowCredentials()
        );
    });

    services.AddAuthentication();
    services.AddMvcCore()
        .AddAuthorization(options => {...});
    services.AddAuthentication("Bearer")
        .AddIdentityServerAuthentication(options => {...});

    services.AddSignalR();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseCors("CorsPolicy");
    app.UseAuthentication();

    app.UseSignalR(routes =>
    {
        routes.MapHub<SampleHub>("/hubs/sample");
    });

    app.UseMvc();
}

Voici mon échantillon de hub

public interface ISampleHubClient 
{
    Task receiveMessage(SampleRequest msg);
}

public class SampleHub : Hub<ISampleHubClient>
{
    private static string _connectionId;

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

        await Clients.Client(Context.ConnectionId).receiveMessage("Subscribed to " + groupName);
    }

    /// <inheritdoc />
    public Task Send(SampleRequest msg)
    {
        ConsoleColor.Green.WriteLine("Send : " + _connectionId);

        return Clients.Group(msg.Group).receiveMessage(msg);
    }
}

Et voici mon code de composant Angular:

import { HubConnection } from '@aspnet/signalr-client';

@Component({})
export class SignalRTestComponent implements OnInit {
    private hubConnection: HubConnection;

    ngOnInit() {
        this.initHub();
    }

    initHub()
    {
        let self = this;
        var signalrBaseUri = "https://localhost:44301/hubs/sample";

       this.hubConnection = new HubConnection(signalrBaseUri);

        this.hubConnection
        .start() // <- Failure here
        .then(() =>{
             self.hubConnection.invoke("Subscribe", this.groupName);
        })
        .catch(err => { console.log("INVOKE FAILED");console.error(err);});             
    })
    .catch(err => 
    {
        console.log('Error while establishing connection :(');
        console.log(err);
    });

    this.hubConnection.on('receiveMessage', (receivedMessage: SampleMessage) => {
        console.log("Message received : ");
        console.log(sampleMessage);
    });
}
}

Toute aide serait grandement appréciée

4
pieperu

Le problème est que le paquet npm a été renommé de @aspnet/signalr-client à @aspnet/signalr. Le passage à ce nouveau paquet et la correction des importations ont fonctionné pour moi (au moins pour éliminer l'erreur d'appel OPTIONS.

import { HubConnection } from '@aspnet/signalr'

5
Thomas

Le commentaire de Pawel m'a laissé dans la bonne direction pour résoudre ce problème.

Voici quelques articles qui traitent de la demande d’OPTIONS et de la décision de la remplacer.

https://github.com/aspnet/SignalR/issues/1107

https://github.com/aspnet/SignalR/issues/1111

Mon problème semble cependant avoir été résolu en corrigeant une erreur avec une version de paquet de nuget.

J'ai réalisé que mon projet SignalR Hub faisait référence à une version préliminaire de Microsoft.AspNetCore.SignalR (2.1.0-preview1-27884). Je l'ai changé pour utiliser 1.0.0-alpha2-final. J'ai également vidé mon répertoire node_modules, vérifié mon cache npm et tout réinstallé

npm cache verify
npm install

Maintenant tout fonctionne correctement. 

0
pieperu

Vous pouvez ignorer l'étape de négociation si vous n'utilisez que des websockets.

this.signalRConnection = new HubConnectionBuilder()
                                 .withUrl(your_url, 
                                         { 
                                            **skipNegotiation: true**, 
                                            **transport: HttpTransportType.WebSockets** 
                                         })
                                 .build();

Dans ce cas, la négociation ne se produit jamais. Vous venez d'obtenir wss: // connection.

0
Roman Olkhovsky