无法使用Angular 5客户端启动与信号器核心集线器的连接

时间:2018-01-05 22:09:56

标签: angular typescript asp.net-core-2.0 kestrel-http-server asp.net-core-signalr

我有一个运行SignalR核心集线器的.Net Core 2.0 C#Web Api。我甚至无法启动()我的hubConnection从angular(5.0.1)收到此错误:

  

选项https://localhost:44301/hubs/sample 405(方法不允许)

     

错误:无法启动连接。错误:方法不允许

     

建立连接时出错:(

     

XHR加载失败:选项“https://localhost:44301/hubs/sample”。

     

HttpError:方法不允许       在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)       在ZoneDelegate.invokeTask(webpack-internal:///../../../../zone.js/dist/zone.js:425:31)       at Object.onInvokeTask(webpack-internal:///../../../core/esm5/core.js:4816:33)       在ZoneDelegate.invokeTask(webpack-internal:///../../../../zone.js/dist/zone.js:424:36)       在Zone.runTask(webpack-internal:///../../../../zone.js/dist/zone.js:192:47)       在ZoneTask.invokeTask [作为调用](webpack-internal:///../../../../zone.js/dist/zone.js:499:34)       at invokeTask(webpack-internal:///../../../../zone.js/dist/zone.js:1540:14)       在XMLHttpRequest.globalZoneAwareCallback(webpack-internal:///../../../../zone.js/dist/zone.js:1566:17)

我正在努力调试这个问题,即使在小提琴手的帮助下我也无法解决它。它似乎不是我的Api的问题,因为Kestrel控制台打印出来到集线器的请求进来,但不会打印任何错误。我能够毫无问题地为我的控制器进行GET,PUT和POST。

这是我的StartUp.cs配置(我省略了与简洁无关的代码)

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();
}

这是我的示例中心

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);
    }
}

这是我的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);
    });
}
}

非常感谢任何帮助

3 个答案:

答案 0 :(得分:5)

问题是@aspnet/signalr-client@aspnet/signalrimport { HubConnection } from '@aspnet/signalr'。更改为新包并修复导入对我有用(至少摆脱OPTIONS调用错误。

thead

答案 1 :(得分:0)

Pawel的评论让我朝着正确的方向解决了这个问题。

以下是一些讨论OPTIONS请求以及替换它的决定的帖子。

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

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

然而,我的问题似乎是通过使用nuget包版本纠正错误来解决的。

我意识到我的SignalR Hub项目引用了Microsoft.AspNetCore.SignalR(2.1.0-preview1-27884)的预览版本。我将其更改为使用 1.0.0-alpha2-final 。我还清理了我的node_modules目录,验证了我的npm缓存,并重新安装了所有内容

npm cache verify
npm install

现在一切正常。

答案 2 :(得分:0)

如果仅要使用网络套接字,则可以跳过协商步骤。

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

在这种情况下,协商永远不会发生。您只获得wss://连接。