简体   繁体   中英

Angular 7 + dotnet core + SignalR IIS Issue

I'm trying to deploy an Angular 7/.net Core application on my local IIS and am running into an issue. I used the Angular template in Visual Studio to create a .net core backend with an Angular front-end. I also added SignalR to both projects. Here are some code samples:

Startup.cs

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

        services.AddSignalR();
        services.AddSpaStaticFiles(configuration =>
        {
            configuration.RootPath = "ClientApp/dist";
        });
    }



public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
    else
{
    app.UseExceptionHandler("/Error");
    // The default HSTS value is 30 days. You may want to change this for 
       production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseStaticFiles();
app.UseSpaStaticFiles();
app.UseCors("CorsPolicy");
app.UseSignalR(routes =>
{
   routes.MapHub<MyHub>("/myHub");
});

app.UseSpa(spa =>
{
    // To learn more about options for serving an Angular SPA from ASP.NET Core,
    // see https://go.microsoft.com/fwlink/?linkid=864501
   spa.Options.SourcePath = "ClientApp";

    if (env.IsDevelopment())
    {
        spa.UseAngularCliServer(npmScript: "start"); 
    }
});
}

connection.service.ts

if (!this.hubConnection) {
    this.hubConnection = new 
    HubConnectionBuilder().withUrl('http://localhost:5000/myhub').build();
}

public start(): void {
    this.hubConnection
    .start()
    .then(() =>  {
        console.log('Connection started');
        this.startingSubject.next();
    })
    .catch((error: any) =>  this.startingSubject.error(error));
  }

data.component.ts

private getAllData(): Promise<Data> {
  const publishDate = this.getPublishDate();
  return this.connectionService.hubConnection.invoke("GetAllData", 
          publishDate);
}

As a quick summary, I have a connection service to handle the signalR connections on the Angular side. Essentially, app.component.ts calls the Start() method in connection.service.ts which starts the SignalR connection. data.component.ts is subscribed to this event and when the connection is successful, it calls the GetAllData() method.

I was trying to follow this tutorial in getting this set up via IIS, but can't get it to work. ( https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/iis/?view=aspnetcore-2.2 )

I Publish from Visual Studio, this creates a directory with my .net Core DLL and a ClientApp folder for my Angular site. If I do a dotnet myapp.dll command I can navigate to localhost:5000 and everything works great.

  • localhost:5000/myhub returns a response from my signalR hub
  • localhost:5000/client shows the signalR client webpage perfectly
  • localhost:5000/host shows the signalR host webpage perfectly.

I should also note that this works when running through VS too. However, when I run through IIS, I get these results:

  • localhost:5000/myhub returns a response from my signalR hub
  • localhost:5000/client shows the signalR client webpage perfectly
  • localhost:5000/host fails with:

ERROR Error: Uncaught (in promise): Error: An unexpected error occurred invoking 'GetAllData' on the server. Error: An unexpected error occurred invoking 'GetAllData' on the server.

/Host does try to make a call to /myhub, which makes me wonder if IIS has an issue with this communicating with the same port or something. or maybe I'm just setting up IIS wrong.

Does anyone have any ideas as to how to get this working via IIS? I'm been scratching my head over this all afternoon.

Edit: After continuing to troubleshoot, it looks like the data.component.ts is successfully calling a "Connect" method on the hub just before the "GetAllData" method.

public Data GetAllData(DateTime? publishDate) 
{
   ... Logic here
}

PublishDate should allow nulls (in this scenario, null is actually being passed to this method), is it possible this isn't allowed for some reason? Again, i have a hard time seeing why this would work everywhere but IIS, but I'm grasping at straws that this point. Seems weird that Connect() would work but GetAllData() wouldn't when they're on the same hub.

One more edit The more I research, the more it looks like there is an actual exception within the GetAllData() method. I'm working at verifying this but I think what's happening is that I have a file path that I'm trying to access but this file path doesn't exist when the application is built. I'm not 100% sure as to why it's failing for IIS only but I'm continuing to dig. I'll post my findings in case anyone else stumbles across this very specific issue :)

I may have missed it.. but where is your MyHub class? Something like this:

 Public class MyHub : Hub {  
  Public async Task GetAllData() {  
      *logic here for when client calls hub*  
   }  
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM