【问题标题】:SignalR Core Apache WS Unexpected response code: 200SignalR Core Apache WS 意外响应代码:200
【发布时间】:2019-12-25 06:22:20
【问题描述】:

我目前正在 Ubuntu Apache Web 服务器上使用 SignalR 运行 .Net Core 应用程序。此 .Net Core 应用可通过 example.com/api 路径访问。

我还在网络服务器上运行了一个 Vue JS 应用程序。当我尝试与 SignalR 应用程序建立 websocket 连接时,出现以下错误:

与“wss://example.com/api/mainHub?id=V3XZrhdsQDTTMIZvQ-8cbQ”的 WebSocket 连接失败:WebSocket 握手期间出错:意外响应代码:200

错误:无法启动传输“WebSockets”:null

.Net Core 应用的 Apache 配置如下:

#Main/Desired Path - https://example.com
<VirtualHost *:443>
        DocumentRoot /var/www/example.com/dist/spa
        ServerName example.com

#SSL Certs
        SSLEngine on
        SSLProtocol all -SSLv2
        SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:!RC4+RSA:+HIGH:+MEDIUM:!LOW:!RC4
        SSLCertificateFile /etc/apache2/ssl/example.crt
        SSLCertificateKeyFile /etc/apache2/ssl/server.key
        SSLCertificateChainFile /etc/apache2/ssl/example.ca-bundle

#Upgrade Websockets
        RewriteEngine on
        RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
        RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
        RewriteRule /(.*) ws://localhost:5000/$1 [P]

#Other specific directories
        ProxyPreserveHost On
        ProxyPass "/api" http://localhost:5000
        ProxyPassReverse "/api" http://localhost:5000

</VirtualHost>

我已经添加了 RewriteEngine 来升级 websocket,我不确定问题出在 Apache 上的配置上,还是在 .Net Core 应用程序本身上。

.Net Core 应用在startup.cs 中有以下内容

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

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            //first handle any websocket requests
            app.UseWebSockets();

            app.UseCors("CorsPolicy");
            app.UseSignalR(routes =>
            {
                routes.MapHub<mainHub>("/mainHub");
                routes.MapHub<accounthub>("/accountHub");
            });
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("Hello World!");
            });
        }

在建立 websocket 连接时,startup.cs 向客户端发送 200 响应似乎有问题,或者 Apache 虚拟主机未正确升级 websocket。

【问题讨论】:

  • 这里的问题完全相同。你找到解决办法了吗?

标签: signalr apache2 kestrel-http-server asp.net-core-signalr kestrel


【解决方案1】:

我在一个站点 (http://shyammakwana.me/server/websockets-with-apache-reverse-proxy-with-ssl.html) 上找到了这个,它似乎也对我有用。 给定站点的 apache 配置应该是这样的

<IfModule mod_ssl.c>
<VirtualHost *:443>
  RewriteEngine On
  ProxyPreserveHost On
  ProxyRequests Off

  # allow for upgrading to websockets
  RewriteEngine On
  RewriteCond %{HTTP:Upgrade} =websocket [NC]
  RewriteRule /(.*)           ws://localhost:5000/$1 [P,L]
  RewriteCond %{HTTP:Upgrade} !=websocket [NC]
  RewriteRule /(.*)           http://localhost:5000/$1 [P,L]


  ProxyPass "/" "http://localhost:5000/"
  ProxyPassReverse "/" "http://localhost:5000/"

  ProxyPass "/chatHub" "ws://localhost:5000/chatHub"
  ProxyPassReverse "/chatHub" "ws://localhost:5000/chatHub"

  ServerName site.com
  
SSLCertificateFile /etc/letsencrypt/live/site.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/site.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>

您还应该启用这些模块:

a2enmod   proxy
a2enmod   proxy_wstunnel

【讨论】:

    【解决方案2】:

    在将 ASP.NET Core 3.1 Blazor 服务器端应用程序部署到运行 Apache2 的 Ubuntu 18.04 服务器时,我也遇到此错误。

    结合此错误,我在尝试从 Linux 服务器访问静态资源(.css 文件、图像和脚本)时也遇到 404 错误,但在 IIS 环境中一切正常。我还注意到,当我发布应用程序时,我的解决方案中 WWWRoot 文件夹的内容似乎没有被复制到 linux 服务器。我使用的是FolderProfile方法发布,然后通过SFTP将发布文件夹的内容复制到linux服务器上。

    我所做的样板 startup.Configure 类(来自 VS2019 中的 New Blazor-Server Web App 模板)的唯一“真正”更改是添加 UseForwardHeaders 指令,如 https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/linux-apache?view=aspnetcore-3.1 所述

    我还在应用程序中添加了身份验证和授权,但再一次,整个事情在 IIS 上完美运行,但一旦测试完成,它需要安装在生产 linux 服务器上。

    我的 Startup.Configure 看起来像:

     public static void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            {
    
                app.UseForwardedHeaders(new ForwardedHeadersOptions
                {
                    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
                });
    
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                    app.UseDatabaseErrorPage();
                }
                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();
                }
    
                // Enable SyncFusion Community Edition License
                Syncfusion.Licensing.SyncfusionLicenseProvider
                    .RegisterLicense("Key-Removed");
    
                app.UseHttpsRedirection();
                app.UseStaticFiles();
    
                app.UseRouting();
    
    
                // Use Authentication and Authorisation providers in the application
                app.UseAuthentication();
                app.UseAuthorization();
    
                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapControllers();
                    endpoints.MapBlazorHub();
                    endpoints.MapFallbackToPage("/_Host");
                });
            }
    

    另外,在 linux 端,虚拟主机配置文件如下所示:

    #<VirtualHost *:*>
    #    RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
    #</VirtualHost>
    
    <VirtualHost *:80>
        ProxyPreserveHost On
        ProxyPass / http://127.0.0.1:5000/
        ProxyPassReverse / http://127.0.0.1:5000/
        ServerName www.grafton.internal
        ErrorLog ${APACHE_LOG_DIR}labapp_error.log
        CustomLog ${APACHE_LOG_DIR}labapp_access.log common
    </VirtualHost>
    

    注意我已经注释掉了前 3 行,因为我无法让这个表达式正常工作 - Apache 未能从我尝试的第二行的每个变体开始。我相信这可能与我的问题有关,但我不知道该怎么办。

    我还想强调,这个应用程序仅供内部使用,网络服务器仅在我们的 Intranet 上可见 - 没有面向外部/互联网的服务器或站点,并且通过物理访问仅限于极少数人访问到服务器,并限制固定 IP 地址,所以我完全不关心使用 SSL。

    对此的任何帮助将不胜感激。我已经尝试让它运行一周了,只剩下一周了,它必须在 linux 测试环境中。

    【讨论】:

      猜你喜欢
      • 2018-05-16
      • 2014-09-21
      • 1970-01-01
      • 2017-07-24
      • 1970-01-01
      • 2021-01-29
      • 2019-07-27
      • 2019-01-21
      • 1970-01-01
      相关资源
      最近更新 更多