I am new to electron and all the documentation on the electron docs use contextIsolation=false
to enable port
to be set globally on window object of the renderer.
I have 2 apps being served and loaded in electron using BrowserWindow
with contextIsolation=true
to limited access to app’s javascript.
Can MessageChannel be used to communicate between these 2 apps/BrowserWindows?
main.js
const { app, BrowserWindow, ipcMain } = require('electron');
const { MessageChannelMain } = require('electron/main');
let mainWindow;
app.on('ready', () => {
mainWindow = new BrowserWindow({
webPreferences: {
contextIsolation: true,
preload: path.join(__dirname, 'preload.js')
}
});
mainWindow.loadURL('your-url');
ipcMain.on('request-port', (event) => {
const { port1, port2 } = new MessageChannelMain();
event.sender.postMessage('port', null, [port2]);
// You can now use port1 for communication in the main process
port1.on('message', (event) => {
console.log('Message from renderer:', event.data);
});
});
});
preload.js
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('electronAPI', {
requestPort: () => ipcRenderer.send('request-port')
});
window.addEventListener('message', (event) => {
if (event.data === 'port') {
const [port] = event.ports;
window.messagePort = port;
port.onmessage = (event) => {
console.log('Message from main process:', event.data);
};
}
});
Here window.addEventListener(‘message’) is never executed. Also, the window
object in the callback differs from the actual window
object due to contextIsolation
.
client.js
document.addEventListener('DOMContentLoaded', () => {
window.electronAPI.requestPort();
document.getElementById('sendMessage').addEventListener('click', () => {
if (window.messagePort) {
window.messagePort.postMessage('Hello from renderer!');
}
});
});