在IIS上托管带有signalR的ASP.NET Core:WebSocket握手期间出错:意外的响应代码:200

时间:2019-03-06 00:37:22

标签: c# websocket iis-8.5 asp.net-core-signalr

我有一个聊天应用程序,当在Visual Studio 2017下使用IIS Express在本地调试时,运行良好。我将其释放到生产环境中后(Windows Server 2012R2 IIS 8.5.9600),javascript控制台向我显示消息:

“与'wss:// [myServer] / [myHubName]?id = [weirdString]'的WebSocket连接失败:WebSocket握手期间出错:意外的响应代码:200”

Altough客户端使用https访问网站,在防火墙处执行ssl解密,因此传入的https请求以端口8088上的http形式到达服务器。

还尝试将我的网站url放在IIS上的网站绑定上的“主机名”选项上,但随后该网站开始返回错误400。

我已经按照microsoft documentation中的说明在IIS上安装了WebSockets支持,并确保我的站点已启用它。

我也在服务器(http)上本地浏览了该网站,并且未出现该错误,因此它似乎与IIS反向代理配置有关。

在IIS运行的同一台计算机上,来自WAN上一个客户端的另一个请求和来自本地客户端的另一个请求都带有一些IIS日志,其中省略了一些私人信息。

IIS log when access was performed from wan:

[lan server ip address] POST /[myHubName]/negotiate - 8088 - https://[public website url]/ 200 0 0 0
[lan server ip address] GET /[myHubName] id=zHiunn5_ynV2jO5812KpDg 8088 -  https://[public website url]/ - 200 0 0 15
[lan server ip address] POST /[myHubName]/negotiate - 8088 -  https://[public website url]/ 200 0 0 78
[lan server ip address] POST /[myHubName] id=T7M5A-o-qqTyd13dSMB64A 8088 - https://[public website url]/ 200 0 0 0

IIS log when access was performed locally on the IIS machine:
::1 POST /[myHubName]/negotiate - 8088 - ::1  http://localhost:8088/ 200 0 0 14
::1 GET /[myHubName] id=QY4do7yqF3EKRbS1Y3usuw 8088 - ::1  - 101 0 64 6356

这两种情况的字段参考是:

#Fields: s-ip cs-method cs-uri-stem cs-uri-query s-port c-ip  sc-status sc-substatus sc-win32-status time-taken

关于如何解决该问题的任何想法?

我的启动代码片段是:

Startup.cs:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        //ommited configuration: authorization, database connection, etc.

        services.AddMvc(options =>
            {
                //some options;

            }).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

        //adds signalR
        services.AddSignalR();

    }


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


        app.UseHttpsRedirection();
        app.UseCookiePolicy();
        app.UseSession();
        app.UseAuthentication();

        app.UseSignalR(routes =>
        {
            routes.MapHub<MyHubName>("/MyHubName");
        });

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


    }
}

Program.cs:

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .UseKestrel()
            .UseIISIntegration();

}

1 个答案:

答案 0 :(得分:1)

现在,我对您的问题有了更多的了解,请确保将IIS绑定设置为在所有ipaddress上侦听,类型= http,主机名=您从WAN使用的url,ipaddress = *,端口= 8088

注意:您在评论中说8088是从防火墙传到服务器的,以访问该应用程序。因此,您不是在服务器上使用https,而是使用http,并且传入流量已由防火墙加密。您不想对路由中的流量进行两次加密。

您还说过,它在服务器上本地工作,所以发生了两件事之一:

  1. 您的服务器仅侦听127.0.0.1 IP地址。更改IIS绑定中的*并使用上​​述正确的端口可以解决该问题。

  2. 流量永远不会使它从网络正确地成为服务器,或者没有正确地返回客户端。

由于2发生了一部分,因此根据您的更新,您需要在某个地方重写URL,这可能会有所帮助:

Websockets reverse proxy in IIS 8

可能不完全一样,但是重写您发送回客户端的流量,以删除端口以匹配用户用来从客户端连接的URL。客户端不知道来自WAN的8088端口。