SignalR Core Apache WS 意外响应代码:200

Bri*_*n S 3 apache2 signalr kestrel kestrel-http-server asp.net-core-signalr

我目前正在 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>
Run Code Online (Sandbox Code Playgroud)

我添加了 RewriteEngine 来升级 websockets,我不确定问题是否出在 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!");
            });
        }
Run Code Online (Sandbox Code Playgroud)

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

小智 5

我在一个网站( 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>
Run Code Online (Sandbox Code Playgroud)

您还应该启用这些模块:

a2enmod   proxy
a2enmod   proxy_wstunnel
Run Code Online (Sandbox Code Playgroud)