我目前正在Ubuntu Apache Web服务器上使用SignalR运行.Net Core应用程序。可以通过example.com/api路径访问此.Net Core应用。
我也有一个在网络服务器上运行的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。
答案 0 :(得分: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
答案 1 :(得分:0)
在将ASP.NET Core 3.1 Blazor服务器端应用程序部署到运行Apache2的Ubuntu 18.04服务器时,我也遇到此错误。
结合此错误,尝试从Linux服务器访问静态资源(.css文件,图像和脚本)时,我也遇到404错误,但在IIS环境中一切正常。我还注意到,当我发布应用程序时,解决方案中WWWRoot文件夹的内容似乎未复制到linux服务器。我正在使用发布的FolderProfile方法,然后通过SFTP将发布文件夹的内容复制到linux服务器。
样板启动时唯一的“真实”更改。配置类(来自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 int CompareTo(QueueEntryElement obj)
{
if (obj == null) return 1;
QueueEntryElement otherQueueEntryElement = obj as QueueEntryElement;
if (otherQueueEntryElement != null)
{
if (Priority.CompareTo(otherQueueEntryElement.Priority) == 0)
{
return OrderId.CompareTo(otherQueueEntryElement.OrderId);
}
return 0;
}
else
throw new ArgumentException("Object is not a QueueEntryElement");
}
此外,在Linux端,虚拟主机配置文件如下所示:
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");
});
}
请注意,我已经注释掉了前三行,因为我无法使该表达式正常工作-Apache无法以我尝试的第二行的每个变体开头。我相信这可能与我的问题有关,但是我不确定该怎么办。
我还想强调一点,该应用程序仅供内部使用,并且Web服务器仅在我们的Intranet上可见-没有面向外部/ Internet的服务器或站点,并且只能通过物理访问来访问极少数人到服务器以及受限制的固定IP地址,因此我完全不关心使用SSL。
对此提供的任何帮助将不胜感激。我一直在努力使它运行一个星期,并且只剩下一个星期才必须在Linux测试环境中进行。