I created a small demo project for SignalR. It all worked when I published my project behind Nginx without SSL. But after I ran Certbot and added SSL to the site all SignalR hubs / WebSockets stopped working. The site can be found here:
signalr.js:5053 WebSocket connection to 'wss://app.topswagcode.com/chatHub?id=v_UmTZyB9v962n44Wf2-Kg' failed:
(anonymous) @ signalr.js:5053
(anonymous) @ signalr.js:5034
step @ signalr.js:4995
(anonymous) @ signalr.js:4976
(anonymous) @ signalr.js:4970
__awaiter @ signalr.js:4966
WebSocketTransport.connect @ signalr.js:5016
HttpConnection.startTransport @ signalr.js:4149
(anonymous) @ signalr.js:4099
step @ signalr.js:3710
(anonymous) @ signalr.js:3691
(anonymous) @ signalr.js:3685
__awaiter @ signalr.js:3681
HttpConnection.createTransport @ signalr.js:4052
(anonymous) @ signalr.js:3970
step @ signalr.js:3710
(anonymous) @ signalr.js:3691
fulfilled @ signalr.js:3682
signalr.js:2150 [2021-06-11T06:43:20.004Z] Error: Failed to start the transport 'WebSockets': Error: There was an error with the transport.
My API Endpoints still works and SSL seems to be working in general.
For deploying my app I followed: https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/linux-nginx?view=aspnetcore-5.0
ran smoothly for normal HTTP connections. Certbot added its SSL stuff and broke my WebSockets 🙁
Edit
So I tried to revert all changes and start over. Instead of redirecting all traffic to SSL (which I should), I have both HTTP and HTTPS
http://app.topswagcode.com/Stock
https://app.topswagcode.com/Stock
Again my Http sockets still works, but HTTPS doesn’t.
My Nginx Setup:
server {
server_name app.topswagcode.com;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /chathub {
proxy_pass http://127.0.0.1:5000/chathub;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_cache_bypass $http_upgrade;
}
listen 80; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/app.topswagcode.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/app.topswagcode.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
I tried to add a chat hub section that I found in some posts. But Didn’t do anything for SSL.
API endpoint’s still working for both HTTP and HTTPS. Still lost about what I did wrong. Most likely something simple in the Nginx config.
For the sake of it, I will be sharing my Startup.cs below here as well. Not much special in id. I have disabled the app.UseHttpsRedirection(); and app.UseHsts();
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddControllers();
services.AddSignalR();
services.AddTransient<IStockService, FakeStockService>();
services.AddHostedService<TimedHostedService>();
services.AddHostedService<StockHostedService>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
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();
}
//app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapControllers();
endpoints.MapHub<ChatHub>("/chathub");
endpoints.MapHub<ProcessHub>("/processhub");
endpoints.MapHub<GraphHub>("/graphhub");
endpoints.MapHub<StockHub>("/stockhub");
});
}
Edit 2
So I just found this:
This request fails only for Https. Request body is:
{"protocol":"json","version":1}
But for HTTPS, it just returns: Not found "No Connection with that ID"
2
Answers
In Startup.js / ConfigureServices:
In Startup.js / Configure:
Unfortunately i totally failed with various custom ssl validation callbacks implementations client-side, so only the server-side solution worked for me:
https://github.com/xamarin/xamarin-android/issues/6351#issuecomment-931987612
(if the link goes down its basically silly deleting the last certificate from 3 present inside your domain fullchain.pem file)
Another solution: https://github.com/xamarin/xamarin-android/issues/6351#issuecomment-946178743
Do not forget to deamon-reload and restart nginx after.