与SignalR集线器的Angular 7连接失败

时间:2019-07-24 06:42:08

标签: c# angular asp.net-web-api2 signalr

尝试在服务器中编写集线器以向客户端广播通知

在我的服务器中: 1-安装了nuget。 2-使用app.MapSignalR()创建Startup.cs; 3-创建的中心:

[HubName("NotificationHub")]
public class NotificationHub : Hub
{
    // required to let the Hub to be called from other server-side classes/controllers, using static methods
    private static IHubContext hubContext = GlobalHost.ConnectionManager.GetHubContext<NotificationHub>();

    // Send the data to all clients (may be called from client JS)
    public void GetNotifications()
    {
        Clients.All.GetNotifications();
    }

    // Send the data to all clients (may be called from server C#)
    public static void GetNotificationsStatic()
    {
        hubContext.Clients.All.GetNotifications();
    }
}

4-创建具有“获取”和“添加”通知的控制器。

在我的客户中: 遵循本指南:https://medium.com/@ghanshyamshukla/implementation-of-signalr-in-angular-5-app-with-asp-net-web-api-2-0-f09672817d4d (在我的angular.json中,而不是在“ ../node_modules ..”中,我已经固定为“ ./node_modules ..”。

这是我的连接功能:

connectToSignalRHub() {
const signalRServerEndPoint = environment.baseURL;
this.connection = $.hubConnection(signalRServerEndPoint);
this.proxy = this.connection.createHubProxy('notificationHub');

this.proxy.on('messageReceived', () => {
  console.log('new notifications');
});
this.connection.start().done((data: any) => {
  console.log('Connected to Notification Hub');
}).catch((error: any) => {
  console.log('Notification Hub error -> ' + error);
});

}

然后,当我运行我的应用程序时,

当尝试与this.connection.start()连接时

我进入错误部分并显示错误:

  

错误:协商请求期间出错。       在Object.error(jquery.signalR.min.js:9)

我在控制台中看到此错误:

  

CORS策略已阻止从来源“ https://localhost:44328/signalr/negotiate?clientProtocol=2.1&connectionData=%5B%7B%22name%22%3A%22notificationhub%22%7D%5D&_=1563949114481”访问“ http://localhost:8083”处的XMLHttpRequest:请求的资源上没有“ Access-Control-Allow-Origin”标头。

不用说我已经为我的应用启用了CORS

3 个答案:

答案 0 :(得分:0)

这对我有用:

我在服务器端使用AspNetCore 2.1(重要版本)。

startup.cs 中:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

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


    services.AddSignalR();
}

services的顺序也很重要。

配置方法:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseBrowserLink();
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }
            app.UseCors("CorsPolicy");
            app.UseStaticFiles();

            app.UseSignalR(route =>
            {
                route.MapHub<NotificationHub>("/notificationHub"); // name of js file
            });

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    enter code here

Hub 类中的

[HubName("NotificationHub")]
public class NotificationHub: Hub
    {
        public Task SendMessage(string user, string message)
        {
            return Clients.All.SendAsync("ReceiveMessage", user, message); // ReceiveMessage => name of method in client
        }
    }

答案 1 :(得分:0)

所以问题是我在WebApiConfig中启用了CORS:

config.EnableCors();
var corsAttr = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(corsAttr);

感谢评论部分中的vasily.sib,他将此链接带给我:CORS Article

我已将Startup.cs配置方法更改为:

app.Map("/signalr", map =>
        {
            // Setup the CORS middleware to run before SignalR.
            // By default this will allow all origins. You can 
            // configure the set of origins and/or http verbs by
            // providing a cors options with a different policy.
            map.UseCors(CorsOptions.AllowAll);
            var hubConfiguration = new HubConfiguration
            {
                // You can enable JSONP by uncommenting line below.
                // JSONP requests are insecure but some older browsers (and some
                // versions of IE) require JSONP to work cross domain
                // EnableJSONP = true
            };
            // Run the SignalR pipeline. We're not using MapSignalR
            // since this branch already runs under the "/signalr"
            // path.
            map.RunSignalR(hubConfiguration);
        });

现在可以使用了。

答案 2 :(得分:0)

花了我几个小时的时间,但最终我将它与http和https结合使用,并删除了端口号后的结尾/

在startup.cs的ConfigureServices方法中

services.AddCors(options => options.AddPolicy("CorsPolicy", builder =>
  {
    builder.AllowAnyMethod()
      .AllowAnyHeader()
      .AllowCredentials()
      .WithOrigins("http://localhost:4200");
  }
));

services.AddSignalR();

在startup.cs的Configure方法中

app.UseCors("CorsPolicy");
app.UseSignalR(routes => routes.MapHub<NotifyHub>("/notify"));

客户端js:

const connection = new signalR.HubConnectionBuilder()
  .withUrl('https://localhost:44394/notify')
  .configureLogging(signalR.LogLevel.Debug)
  .build();

connection.start().then(() => {
  console.log('Connected!');
}).catch((err) => {
  return console.error(err.toString());
});

可能还有其他一些成功的组合,但是感觉就像我尝试了每个组合,但我还没有准备好在它最终运行时继续尝试…