【问题标题】:SignalR SSE handshake failsSignalR SSE 握手失败
【发布时间】:2019-01-20 02:04:31
【问题描述】:

在“Windows Server 2008 R2”上托管一个 ASP.Net Core 2.1 webapi 和一个 Angular 6 webapp,使用相同的域名但不同的端口(分别为:81 和 :80);不包含在同一个文件夹中。

根据this article,SSE 是 Websocket 不可用时的(标准)回退,这是预期的,因为服务器不支持 Websocket,因为它们是在 IIS 8.0 中引入的 (server is IIS 7.5)

在开发中,一切正常。但是,发布后,浏览器控制台会在 15 秒后报告以下内容(可能是默认的“HandshakeTimeout”时间)。

> Information: SSE connected to http://my.website.com:81/notify?id=kaSkcGUjcZD4ylJAC7B70A
> Error: Connection disconnected with error 'Error: Server returned handshake error: Handshake was canceled.'.
> Error: Not Found

Startup.cs 当前设置如下:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSignalR();
    services.AddMemoryCache();
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    services.AddCors(o => {
        o.AddPolicy("Limited", builder => builder
            .WithOrigins("http://my.website.com") // .AllowAnyOrigin() also tested and worked
            .AllowAnyMethod()
            .AllowAnyHeader()
            .AllowCredentials()
        );
    });
    services.AddDbContext<DatabaseContext>(options => {
        options.UseSqlServer(Configuration.GetConnectionString("Database"));
    });
}

public void Configure(
    IApplicationBuilder app,
    IHostingEnvironment env,
    IServiceProvider serviceProvider)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseHsts();
    }

    app.UseCors("Limited");
    app.UseHttpsRedirection();
    app.UseMvc();
    app.UseSignalR(routes => routes.MapHub<NotifyHub>("/notify"));
}

SignalR Hub 几乎是空的(事件推送在其他地方处理):

public class NotifyHub : Hub
{
    public override async Task OnConnectedAsync()
    {
        await base.OnConnectedAsync();
    }

    public override async Task OnDisconnectedAsync(Exception exception)
    {
        await base.OnDisconnectedAsync(exception);
    }
}

Angular 服务设置如下:

import { Injectable } from '@angular/core';
import { HubConnection } from '@aspnet/signalr';
import * as signalR from '@aspnet/signalr';
import { Subject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class RefreshService {
  private connection: HubConnection;
  public timestamp = new Subject<string>();

  constructor(private zone: NgZone) {
    this.connection = new signalR.HubConnectionBuilder()
      .withUrl(http://my.website.com:81/notify)
      .build();

    this.connection
      .start()
      .then(() => {
        this.connection.on('Message', data => {
          // Do Work
        });
      })
      .catch(err => console.error(err.toString()));
  }
}

所有 NuGet 包都是最新的(v2.1.1 适用于除 Microsoft.NETCore.App 之外的所有内容,即 v2.1.0)并使用 v1.0.2(最新)ASP.NET SignalR NPM package - 所以服务器端和客户端SignalR 是一样的。

使用静态 IP 地址,我能够让应用连接到本地发布的 API(但运行 IIS 10.0)。

我有什么遗漏吗?很多技术都很新,但我还不想假设它们有问题。

【问题讨论】:

  • 你解决了这个问题吗?
  • @Esen 不幸的是没有
  • 我在 Web 服务器和客户端上都禁用了卡巴斯基防火墙和 windows 防火墙,它开始工作。试一试。

标签: signalr angular6 windows-server-2008-r2 asp.net-core-webapi asp.net-core-2.1


【解决方案1】:

如果有人仍然面临这个问题,我通过在 IIS 上配置 IIS 8.0 WebSocket 协议支持来解决它。

Microsoft documentation

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-28
    • 2017-06-19
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多