我目前正在 Ubuntu Apache Web 服务器上运行带有 SignalR 的 .Net Core 应用程序。此 .Net Core 应用可通过 example.com/api 路径访问。
我还有一个在网络服务器上运行的 Vue JS 应用程序。当我尝试与 SignalR 应用程序建立 websocket 连接时,出现以下错误:
WebSocket connection to 'wss://example.com/api/mainHub?id=V3XZrhdsQDTTMIZvQ-8cbQ' failed: Error during WebSocket handshake: Unexpected response code: 200
Error: Failed to start the transport '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 来升级 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!");
});
}
似乎 startup.cs
中的某些内容不正确,在建立 websocket 连接时向客户端发送 200 响应,或者 Apache 虚拟主机没有正确升级 websocket。
最佳答案
我在网站 ( 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
关于SignalR 核心 Apache WS 意外响应代码 : 200,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57566771/