- Add authenticationToken field to store GUID
- Generate secure token using Guid.NewGuid().ToString('N')
- Pass token to Electron via --authtoken command-line parameter
- Token is 32 hex characters with 128 bits of entropy
HSTS and HTTPS redirection are designed for public web servers, not
desktop applications:
- ASP.NET Core only listens on http://localhost (local-only)
- No man-in-the-middle risk for same-machine communication
- HTTPS would require certificate setup with no security benefit
- HTTPS overhead slows down local IPC unnecessarily
Electron apps should use plain HTTP for localhost communication.
SignalR's MapHub<T>() automatically enables WebSocket support, making
explicit UseWebSockets() redundant. SignalR also supports fallback
transports (Server-Sent Events, Long Polling) if WebSockets are unavailable.
Updated documentation to reflect this and clarify that WebSockets are
enabled automatically by MapHub().
Changed from app.UseEndpoints() pattern to direct app.MapHub() call,
following modern ASP.NET Core conventions. This removes the analyzer
warning while maintaining the same functionality.
Added comprehensive code comments explaining:
- RuntimeControllerAspNetDotnetFirstSignalR: .NET-first startup flow and key differences from Socket.IO
- SignalRFacade: Type conversion handling and event propagation details
- signalr-bridge.js: Socket.IO compatibility layer and arg handling
- main.js: Keep-alive window pattern and SignalR startup sequence
Comments focus on explaining WHY decisions were made, not just WHAT the code does.
- Fix middleware order: UseAntiforgery must be between UseRouting and UseEndpoints
- Add UseStaticFiles() to serve wwwroot content
- Fix scoped CSS bundle reference: use lowercase 'electronnet-samples-blazorsignalr.styles.css' to match generated asset name
- Add HTTP request logging for debugging
- Enable detailed logging for routing and static files in development
- Destroy keep-alive window when first real window is created (enables proper window-all-closed behavior)
- Update ElectronNetRuntime.AspNetWebPort with actual port after Kestrel starts (fixes http://localhost:0 issue)
- Fix duplicate SignalR connection in main.js (removed redundant connect block)
- Fix race condition: Electron now signals 'electron-host-ready' after loading API modules
- Fix type conversion in SignalRFacade for event handlers (handle JsonElement and numeric types)
- Fix SignalR argument mismatch: pass args as array instead of spread, use object[] instead of params
- .NET now waits for electron-host-ready before calling app ready callback
ROOT CAUSE: Electron quits when app.on('ready') completes with 0 windows.
In SignalR mode, no windows are created immediately, so Electron exits,
triggering ElectronProcess_Stopped and shutting down ASP.NET.
SOLUTION: Create an invisible 1x1 keep-alive window in SignalR mode to
prevent Electron from quitting while waiting for SignalR connection.
Also:
- Make app.on('ready') async and await startSignalRApiBridge()
- Add window-all-closed handler for SignalR mode
- Add extensive debug logging to track lifecycle
- Don't subscribe to electronProcess.Ready in SignalR controller
This fixes the premature shutdown that prevented SignalR connection.
- Add WebSockets middleware to ASP.NET pipeline
- Move HTTPS redirect to production only
- Add extensive debug logging in startSignalRApiBridge
- Enable Warning level logging in SignalR client
Issue: signalRBridge.connect() hangs and never resolves
- Connection starts but never completes
- No error messages from SignalR client
- ASP.NET shuts down after timeout
- ElectronHub.OnConnectedAsync never called
Next: Investigate why WebSocket connection doesn't establish
- Wrap all console.log/error calls in try-catch to handle EPIPE
- Disable SignalR client logging (LogLevel.None)
- Prevents Electron crash when console pipes are closed
This fixes the 'EPIPE: broken pipe, write' error that was preventing
the Electron window from displaying.
- Add RunReadyCallback execution when SignalR connects
- This triggers window creation and other app initialization
- Fixes missing variables in main.js (desktopCapturer, electronHostHook, touchBar, shellApi)
- Window now opens successfully in SignalR mode
Known issue: EPIPE console error when logging to closed pipe (to be fixed)
- Update signalr-bridge.js to handle .NET→Electron events via 'event' channel
- Add socket.io-compatible .on() and .emit() methods to SignalRBridge
- Update main.js to load all Electron API modules with SignalR bridge
- Update SignalRFacade.Emit() to send events via 'event' channel
- Add ElectronHub.ElectronEvent() to receive Electron→.NET events
- Add SignalRFacade.TriggerEvent() to invoke .NET event handlers
- Remove duplicate ElectronEvent method from hub
This enables full bidirectional communication:
- .NET can call Electron APIs via Emit (e.g., createBrowserWindow)
- Electron can send events back to .NET (e.g., BrowserWindowCreated)
- Event handlers registered via On/Once now work with SignalR
- Create IFacade interface defining common API for SocketIO and SignalR
- Update SocketIoFacade to implement IFacade
- Update SignalRFacade to implement IFacade (add Connect no-op)
- Update RuntimeControllerBase.Socket to return IFacade
- Update RuntimeControllerAspNetBase.Socket to return IFacade
- Update RuntimeControllerDotNetFirst.Socket to return IFacade
- Update ElectronNetRuntime.GetSocket() to return IFacade
- Update BridgeConnector.Socket to return IFacade
This enables polymorphic usage of both facades throughout the codebase
and prepares for full Electron API integration with SignalR mode.