Skip to content

Can I share an IPC channel with multiple processes?

Tldr

Multiple renderer processes can invoke the main process on the same channel. The main process always respond to the correct renderer process.

Main Process

The main process starts four renderer processes. Each one of them will invoke the main process on the echo channel.

main.js
const {app, BrowserWindow, ipcMain} = require('electron');
const path = require('path');

app.whenReady().then(async () => {
  const winDef = {
    width: 200,
    height: 400,
    webPreferences: {
      nodeIntegration: false,
      contextIsolation: true,
      preload: path.resolve(__dirname, 'preload.js')
    }
  };

  const bwin1 = new BrowserWindow({ title: 'FOO', x:  20, y: 60, ...winDef});
  const bwin2 = new BrowserWindow({ title: 'BAR', x: 230, y: 60, ...winDef});
  const bwin3 = new BrowserWindow({ title: 'BAZ', x: 440, y: 60, ...winDef});
  const bwin4 = new BrowserWindow({ title: 'BAT', x: 650, y: 60, ...winDef});

  await bwin1.loadFile('renderer.html'); bwin1.show();
  await bwin2.loadFile('renderer.html'); bwin2.show();
  await bwin3.loadFile('renderer.html'); bwin3.show();
  await bwin4.loadFile('renderer.html'); bwin4.show();

  ipcMain.handle('echo', (_, any) => any);
});

Preload Script

The MY_APP.echo method will invoke the main process on the echo channel with some value. The main process simply answer back with the same value.

preload.js
const {contextBridge, ipcRenderer} = require('electron');

contextBridge.exposeInMainWorld('MY_APP', {
  echo(any) {
    return ipcRenderer.invoke('echo', any);
  }
});

Renderer Page

Each renderer process creates a unique random value at the start and keep sending it back to the main process which responds by echoing back that same value.

renderer.html
<html>

<head>
  <style>
    body {background-color:black;color:limegreen}
  </style>
</head>

<body>
  <div id="response"></div>
  <script>
    const rand = Math.random();
    setInterval(() => {
      MY_APP.echo(rand).then(any => {
        document.querySelector('#response').innerHTML += `${any}<br>`;
      });
    }, 1000);
  </script>
</body>

</html>

Screenshot