diff --git a/src/ElectronNET.AspNet/Bridge/SignalRFacade.cs b/src/ElectronNET.AspNet/Bridge/SignalRFacade.cs
index 54216d9..d270d98 100644
--- a/src/ElectronNET.AspNet/Bridge/SignalRFacade.cs
+++ b/src/ElectronNET.AspNet/Bridge/SignalRFacade.cs
@@ -116,8 +116,10 @@ namespace ElectronNET.API
try
{
- // Send message to specific Electron client
- await _hubContext.Clients.Client(_connectionId).SendAsync(eventName, args);
+ // Send message to specific Electron client via the 'event' hub method
+ // This will be received by signalr-bridge.js's connection.on('event', ...)
+ Console.WriteLine($"[SignalRFacade] Emitting event '{eventName}' to connection {_connectionId}");
+ await _hubContext.Clients.Client(_connectionId).SendAsync("event", eventName, args);
}
catch (Exception ex)
{
@@ -126,12 +128,20 @@ namespace ElectronNET.API
}
}
- public void TriggerEvent(string eventName, object data)
+ public void TriggerEvent(string eventName, params object[] args)
{
+ Console.WriteLine($"[SignalRFacade] Triggering event '{eventName}' for .NET handlers");
+
if (_eventHandlers.TryGetValue(eventName, out var handler))
{
+ // If single arg, pass it directly; otherwise pass the array
+ var data = args.Length == 1 ? args[0] : args;
handler(data);
}
+ else
+ {
+ Console.WriteLine($"[SignalRFacade] No handler registered for event '{eventName}'");
+ }
}
public void DisposeSocket()
diff --git a/src/ElectronNET.AspNet/Hubs/ElectronHub.cs b/src/ElectronNET.AspNet/Hubs/ElectronHub.cs
index c7e6e73..18c0962 100644
--- a/src/ElectronNET.AspNet/Hubs/ElectronHub.cs
+++ b/src/ElectronNET.AspNet/Hubs/ElectronHub.cs
@@ -60,6 +60,27 @@ namespace ElectronNET.AspNet.Hubs
await Task.CompletedTask;
}
+ ///
+ /// Receives events from Electron (e.g., "BrowserWindowCreated", "dialogResult").
+ /// Called by Electron to send data back to .NET.
+ ///
+ /// The event name
+ /// The event arguments
+ public async Task ElectronEvent(string eventName, params object[] args)
+ {
+ Console.WriteLine($"[ElectronHub] Received event from Electron: {eventName}");
+
+ // Get the SignalRFacade and trigger the event handlers
+ var runtimeController = ElectronNetRuntime.RuntimeController as RuntimeControllerAspNetDotnetFirstSignalR;
+ if (runtimeController?.Socket is ElectronNET.API.SignalRFacade signalRFacade)
+ {
+ // Invoke the event handlers registered via On/Once
+ signalRFacade.TriggerEvent(eventName, args);
+ }
+
+ await Task.CompletedTask;
+ }
+
///
/// Invokes an Electron API method. Called by .NET to control Electron.
///
@@ -91,17 +112,5 @@ namespace ElectronNET.AspNet.Hubs
await Task.CompletedTask;
}
- ///
- /// Handles events from Electron.
- /// Called by Electron to notify .NET about events (e.g., window closed).
- ///
- /// The event name
- /// The event data as JSON
- public async Task ElectronEvent(string eventName, string eventData)
- {
- Console.WriteLine($"[ElectronHub] ElectronEvent received: {eventName}");
- // This will be handled by the event system
- await Task.CompletedTask;
- }
}
}
diff --git a/src/ElectronNET.Host/api/signalr-bridge.js b/src/ElectronNET.Host/api/signalr-bridge.js
index d3f631a..98b2e3e 100644
--- a/src/ElectronNET.Host/api/signalr-bridge.js
+++ b/src/ElectronNET.Host/api/signalr-bridge.js
@@ -6,7 +6,7 @@ class SignalRBridge {
this.hubUrl = hubUrl;
this.connection = null;
this.isConnected = false;
- this.pendingCalls = new Map(); // For tracking API calls
+ this.eventHandlers = new Map(); // For socket.io-style .on() handlers
this.callIdCounter = 0;
}
@@ -56,46 +56,46 @@ class SignalRBridge {
}
setupMessageHandlers() {
- // Handle API calls from .NET
- this.connection.on('electronApiCall', (method, data) => {
- console.log(`[SignalRBridge] Received API call: ${method}`);
- this.handleApiCall(method, data);
+ // Handle generic events from .NET - this is where .NET's Emit() calls arrive
+ this.connection.on('event', (eventName, ...args) => {
+ console.log(`[SignalRBridge] Received event: ${eventName}`);
+
+ // Check if we have handlers registered for this event
+ if (this.eventHandlers.has(eventName)) {
+ const handlers = this.eventHandlers.get(eventName);
+ handlers.forEach(handler => {
+ try {
+ handler(...args);
+ } catch (err) {
+ console.error(`[SignalRBridge] Error in event handler for ${eventName}:`, err);
+ }
+ });
+ }
});
}
- async handleApiCall(method, data) {
- // This will be implemented to route to the actual Electron API
- // For now, just log it
- console.log(`[SignalRBridge] Handling API call: ${method} with data:`, data);
-
- // TODO: Route to actual Electron API handlers
- // This will be connected to the existing API modules (browserWindows, dialog, etc.)
+ // Socket.io compatibility: register event handler
+ on(eventName, callback) {
+ if (!this.eventHandlers.has(eventName)) {
+ this.eventHandlers.set(eventName, []);
+ }
+ this.eventHandlers.get(eventName).push(callback);
+ console.log(`[SignalRBridge] Registered handler for event: ${eventName}`);
}
- async invokeMethod(methodName, ...args) {
+ // Socket.io compatibility: emit event (send to .NET)
+ async emit(eventName, ...args) {
if (!this.isConnected) {
- throw new Error('SignalR connection is not established');
- }
-
- try {
- const result = await this.connection.invoke(methodName, ...args);
- return result;
- } catch (err) {
- console.error(`[SignalRBridge] Error invoking ${methodName}:`, err);
- throw err;
- }
- }
-
- async sendElectronEvent(eventName, eventData) {
- if (!this.isConnected) {
- console.warn(`[SignalRBridge] Cannot send event - not connected`);
+ console.warn(`[SignalRBridge] Cannot emit ${eventName} - not connected`);
return;
}
try {
- await this.connection.invoke('ElectronEvent', eventName, JSON.stringify(eventData));
+ console.log(`[SignalRBridge] Emitting event: ${eventName}`);
+ await this.connection.invoke('ElectronEvent', eventName, ...args);
} catch (err) {
- console.error(`[SignalRBridge] Error sending event:`, err);
+ console.error(`[SignalRBridge] Error emitting ${eventName}:`, err);
+ throw err;
}
}
@@ -106,19 +106,6 @@ class SignalRBridge {
console.log(`[SignalRBridge] Disconnected`);
}
}
-
- // Socket.io compatibility method - for easier transition
- on(eventName, callback) {
- if (this.connection) {
- this.connection.on(eventName, callback);
- }
- }
-
- // Socket.io compatibility method
- emit(eventName, ...args) {
- // Map to SignalR invoke
- return this.invokeMethod(eventName, ...args);
- }
}
module.exports = { SignalRBridge };
diff --git a/src/ElectronNET.Host/main.js b/src/ElectronNET.Host/main.js
index d7e5fc7..fa2e896 100644
--- a/src/ElectronNET.Host/main.js
+++ b/src/ElectronNET.Host/main.js
@@ -427,11 +427,31 @@ async function startSignalRApiBridge(baseUrl) {
// Store the bridge globally for API access
global['electronsignalr'] = signalRBridge;
- // Load API modules with SignalR bridge
+ // Load API modules with SignalR bridge (same as socket.io)
console.log('[SignalRBridge] Loading API components...');
- // TODO: Load API modules adapted for SignalR
- // For now, just log that we're connected
+ if (appApi === undefined) appApi = require('./api/app')(signalRBridge, app);
+ if (browserWindows === undefined) browserWindows = require('./api/browserWindows')(signalRBridge, app);
+ if (commandLine === undefined) commandLine = require('./api/commandLine')(signalRBridge, app);
+ if (autoUpdater === undefined) autoUpdater = require('./api/autoUpdater')(signalRBridge);
+ if (ipc === undefined) ipc = require('./api/ipc')(signalRBridge);
+ if (menu === undefined) menu = require('./api/menu')(signalRBridge);
+ if (dialogApi === undefined) dialogApi = require('./api/dialog')(signalRBridge);
+ if (notification === undefined) notification = require('./api/notification')(signalRBridge);
+ if (tray === undefined) tray = require('./api/tray')(signalRBridge);
+ if (webContents === undefined) webContents = require('./api/webContents')(signalRBridge);
+ if (globalShortcut === undefined) globalShortcut = require('./api/globalShortcut')(signalRBridge);
+ if (clipboard === undefined) clipboard = require('./api/clipboard')(signalRBridge);
+ if (screen === undefined) screen = require('./api/screen')(signalRBridge);
+ if (shell === undefined) shell = require('./api/shell')(signalRBridge);
+ if (nativeTheme === undefined) nativeTheme = require('./api/nativeTheme')(signalRBridge);
+ if (powerMonitor === undefined) powerMonitor = require('./api/powerMonitor')(signalRBridge);
+ if (dock === undefined) dock = require('./api/dock')(signalRBridge, app);
+ if (desktopCapturer === undefined) desktopCapturer = require('./api/desktopCapturer')(signalRBridge);
+ if (electronHostHook === undefined) electronHostHook = require('./api/hostHook')();
+ if (process.platform === 'darwin') {
+ if (touchBar === undefined) touchBar = require('./api/touchBar')(signalRBridge);
+ }
console.log('[SignalRBridge] Startup complete');