2020年12月29日 星期二

[electron, react, ipc] How to communicate Main and Render processes in Electron App

 

How to communicate Main and
Render processes in Electron App

井民全, Jing, mqjing@gmail.com

Source: Github


A running Electron App can be separated as two processes[1]:

  1. Main process: bring up a browser, load the render html, index.html and run your index.js
    in the Render process

  2. Render process: render your application by processing corresponding web pages.

You can do system level stuff in Main process such as File I/O, IoT device I/O and then
send the status update message via IPC to the Render process via IPC (interprocess
communication). The document shows you how to do that.


Enjoy!

By Jing.


1. Render -> Electron main

1.1. Render

File: index.tsx

//const { ipcRenderer } = window.require("electron");

const { ipcRenderer} = window.require("electron");


// Create the browser window.

    mainWindow = new BrowserWindow({

            width: 800, height: 600,

            webPreferences: {

                    nodeIntegration: true,

              }

        });

..

let lstData:Array<number|string> = [1, 'string'];

ipcRenderer.invoke('perform-action', lstData);


1.2. Main process

File: main.ts

// In the Main process

import { ipcMain } from 'electron';


ipcMain.handle('perform-action', (event, ...args) => {

  // ... do actions on behalf of the Renderer

  console.log('ipcMain hello');

})



2. Electron main -> Render

2.1. Main process

// In the Main process

// main process --> render process


mainWindow.webContents.on('did-finish-load', () => {

   if (mainWindow === null){

            return;

    }

    mainWindow.webContents.send('fromMainProcess', 'whoooooooh!')

})


Full

File: src/main.ts

let mainWindow:BrowserWindow|null;


function createWindow() {

    // Create the browser window.

    mainWindow = new BrowserWindow({

            width: 800, height: 600,

            webPreferences: {

                    nodeIntegration: true,

              }

        });


    const startUrl = process.env.ELECTRON_START_URL || url.format({

        pathname: path.join(__dirname, '/../build/index.html'),

        protocol: 'file:',

        slashes: true

    });

    mainWindow.loadURL(startUrl);


    // main process --> render process

    mainWindow.webContents.on('did-finish-load', () => {

          if (mainWindow === null){

                return;

          }

          mainWindow.webContents.send('fromMainProcess', 'whoooooooh!')

      })

}


2.2. Render

File: src/index.tsx

const { ipcRenderer, IpcRendererEvent } = window.require("electron");


ipcRenderer.on('fromMainProcess', (event: typeof IpcRendererEvent, ...args:Array<any>) => {

  console.log('args from Main process = ' + args) // Prints 'whoooooooh!'

})



3. Run

yarn build

yarn electron // "electron": "tsc src/main.ts && cp ./src/main.js ./build/main.js && electron ."


4. References

  1. https://www.electronjs.org/docs/tutorial/quick-start#main-and-renderer-processes

  2. https://www.electronjs.org/docs/api/ipc-renderer

  3. https://www.electronjs.org/docs/api/web-contents#contentssendchannel-args