From fe8fa736921c17aa5a1cb04fbfae569b5add40a4 Mon Sep 17 00:00:00 2001 From: Michal Vrba Date: Fri, 30 Jan 2026 17:26:01 +0100 Subject: [PATCH] Add SignalR/WebSocket config and large upload support Configured SignalR and WebSockets for improved reliability and large content handling. Added appsettings and web.config for production/IIS, including increased timeouts, message size limits, and security/compression settings. Added fallback to Long Polling if WebSockets fail. --- Notemark/Components/App.razor | 9 ++++ Notemark/Program.cs | 17 +++++++ appsettings.Production.json | 16 ++++++ appsettings.json | 54 ++++++++++++++++++++ web.config | 96 +++++++++++++++++++++++++++++++++++ 5 files changed, 192 insertions(+) create mode 100644 appsettings.Production.json create mode 100644 appsettings.json create mode 100644 web.config diff --git a/Notemark/Components/App.razor b/Notemark/Components/App.razor index 81f5fa8..ab414e3 100644 --- a/Notemark/Components/App.razor +++ b/Notemark/Components/App.razor @@ -24,6 +24,15 @@ document.addEventListener('DOMContentLoaded', function() { notemarkTheme.init(); }); + + // Force Long Polling if WebSockets fail (temporary fix) + Blazor.start({ + configureSignalR: function (builder) { + builder.withUrl("/_blazor", { + transport: 1 // LongPolling = 1, WebSockets = 4 + }); + } + }); diff --git a/Notemark/Program.cs b/Notemark/Program.cs index 0adda16..feab57c 100644 --- a/Notemark/Program.cs +++ b/Notemark/Program.cs @@ -15,6 +15,16 @@ builder.Services.AddSingleton(); builder.Services.AddScoped(); builder.Services.AddScoped(); +// Configure SignalR for better WebSocket support +builder.Services.AddSignalR(options => +{ + // Increase timeouts for large content + options.ClientTimeoutInterval = TimeSpan.FromMinutes(2); + options.KeepAliveInterval = TimeSpan.FromSeconds(30); + options.HandshakeTimeout = TimeSpan.FromSeconds(30); + options.MaximumReceiveMessageSize = 1024 * 1024; // 1MB +}); + var app = builder.Build(); // Configure the HTTP request pipeline. @@ -27,6 +37,13 @@ if (!app.Environment.IsDevelopment()) app.UseStatusCodePagesWithReExecute("/not-found", createScopeForStatusCodePages: true); app.UseHttpsRedirection(); +// Enable WebSockets +app.UseWebSockets(new WebSocketOptions +{ + KeepAliveInterval = TimeSpan.FromMinutes(2), + ReceiveBufferSize = 4 * 1024 +}); + // Enable cookies for session management app.UseCookiePolicy(new CookiePolicyOptions { diff --git a/appsettings.Production.json b/appsettings.Production.json new file mode 100644 index 0000000..bb9a44a --- /dev/null +++ b/appsettings.Production.json @@ -0,0 +1,16 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Warning", + "Microsoft.AspNetCore": "Warning", + "Microsoft.AspNetCore.SignalR": "Warning", + "Microsoft.AspNetCore.Http.Connections": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "AllowedHosts": "*", + + "SignalR": { + "EnableDetailedErrors": false + } +} \ No newline at end of file diff --git a/appsettings.json b/appsettings.json new file mode 100644 index 0000000..7a9919c --- /dev/null +++ b/appsettings.json @@ -0,0 +1,54 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning", + "Microsoft.AspNetCore.SignalR": "Information", + "Microsoft.AspNetCore.Http.Connections": "Information" + }, + "Console": { + "IncludeScopes": false, + "LogLevel": { + "Default": "Warning" + } + } + }, + "AllowedHosts": "*", + + "Kestrel": { + "Limits": { + "MaxRequestBodySize": 104857600, + "RequestHeadersTimeout": "00:01:00", + "KeepAliveTimeout": "00:02:00", + "MaxRequestHeaderCount": 100, + "MaxRequestHeadersTotalSize": 65536, + "MaxRequestLineSize": 8192, + "MaxRequestBufferSize": 1048576, + "MaxResponseBufferSize": 1048576 + }, + "EndPoints": { + "Http": { + "Url": "http://localhost:5000" + } + } + }, + + "SignalR": { + "SupportedProtocols": [ "WebSockets", "LongPolling" ], + "ClientTimeoutInterval": "00:02:00", + "KeepAliveInterval": "00:00:30", + "HandshakeTimeout": "00:00:30", + "MaximumReceiveMessageSize": 1048576, + "StreamBufferCapacity": 10, + "EnableDetailedErrors": false + }, + + "ConnectionStrings": {}, + + "AppSettings": { + "DataPath": "data", + "MaxFileSize": 104857600, + "SessionTimeout": "30.00:00:00", + "ShareTokenExpiry": "365.00:00:00" + } +} \ No newline at end of file diff --git a/web.config b/web.config new file mode 100644 index 0000000..de65e79 --- /dev/null +++ b/web.config @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file