SoFunction
Updated on 2025-04-07

Implementation of Electron inter-process communication

Desktop applications developed using Electron are multi-process, including a main process and at least one rendering process (Renderer).

The main process controls the entire application life cycle, interacts with the GUI through some modules in electron, and controls each rendering process at the same time.

The rendering process will render a web page in the window created by the BrowserWindow object, and each rendering page runs in an independent process.

Communication between the main process and the rendering process

ipc module +

The ipc module includes two modules: ipcMain and ipcRenderer. Among them, ipcMain is used in the main process and ipcRenderer is used in the rendering process. Before use, you need to use require to introduce the corresponding module.

Methods in the ipc module:

  • (msg, () => {}): Listen to the msg message sent by the rendering process and respond.
  • (msg, () => {}): Listen to the msg message sent by the rendering process and respond, but automatically removes the listener after listening to a msg event.
  • (msg, () => {}): Listen to the msg message sent by the main process and respond.
  • (msg, () => {}): Listen to the msg message sent by the main process and respond, but automatically removes the listener after listening to a msg event.
  • (msg, data): Listen to the rendering process to send msg asynchronous messages to the main process and carry parameter data.
  • (msg, data): Listen to the rendering process to send msg synchronization messages to the main process and carry parameters
  • (webContentId, msg, data): Listen to the rendering process to send a message to a window with webContentId
  • (msg, data): Listen to the rendering process to send a message to the <webview> element on the host page

The ipc module also provides methods to delete specified listeners and delete all listeners: removeListener() and removeAllListener(). These two methods are used the same in the two modules: ipcMain and ipcRenderer.

Through the above several listeners, we found that using the ipc module alone cannot realize that the main process actively sends messages to the rendering process. So I usually use the webContents and ipc module in the BrowserWindow instance

An example of communication between main process and rendering process

// Use ipcMain in the main processconst { ipcMain, BrowserWindow } = require('electron');

window = new BrowserWindow({
    width: 800,
    height: 600
});

// The main process actively sends messages to the rendering process('main webContents msg', data);

// The main process receives the message sent by the rendering process and responds through the callback function('renderer ipc msg', (event, arg) =&gt; {
    // TODO something
})
// Use ipcRender in rendering processconst ipcRender = require('electron');

// Receive main process messages in the rendering process and make corresponding calls through the callback function('main webContents msg', (event, arg) =&gt; {
    // When the corresponding main process event is used, another message is sent through the method like the main process    ('renderer ipc msg', data);
})

Synchronous and asynchronous messages sent by ipcRenderer

Among the several methods listed above, the method of ipcRenderer sending messages is divided into a method of sending synchronous messages and a method of sending asynchronous messages. When the main program listens to messages from these two different methods, it can return messages to the rendering process in different ways:

// Rendering process
// The rendering process sends asynchronous messages('msg', data);

// The rendering process sends a synchronization message.  Send synchronous messages, block other operations when the task is not completedvar message = ('sync msg', data);
('msg', (event, arg) =&gt; {
    // After the main process monitors the asynchronous message sent by the rendering process, it responds through () method. You can use the 'return msg' message to listen for in the rendering process    ('return msg', data)
})

('sync msg', (event, arg) =&gt; {
     = 'msg';
})

remote module

Using remote in the rendering process allows you to call some methods provided by the main process. (For example: dialog, menu and other modules)

const { BrowserWindow } = require('electron').remote;

// Through the remote module, the BrowserWindow module can be called in the rendering processlet win = new BrowserWindow({ width: 800, height: 600});
('');

Objects returned by remote module in the rendering process represent an object in the main process, generally called a remote object. When calling the method of the remote object, you are actually thinking that the main process sends a synchronization message.

For example, in the above code, the BrowserWindow instance is returned through the remote module, so the BrowserWindow and win in the rendering process are both remote objects. When executing the new BrowserWindow({...}), the object of the BrowserWindow instance is not created in the rendering process, but the BrowserWindow object is created in the main process and the object is returned to the rendering process.

Methods and properties of remote

  • (module): Returns the object in the main process
  • (): Return to the window to which this web page belongs
  • (name): Returns the global variable of name in the main process
  • : Return the process object in the main process

Communication between rendering processes

After testing, the communication methods mentioned above cannot be directly communicated between rendering processes. Sometimes, in our development, we can use the main process as a relay for communication between rendering processes:

// renderer process A
const { ipcRenderer } = require('electron');
('A send msg', data);
// main process
const { ipcMain, BrowserWindow } = require('electron');

let win = new BrowserWindow({...});

('A send msg', (event ,arg) => {
    // TODO something
    ('main send msg', data);
})
const { ipcRenderer } = require('electron');
('main send msg', (event, arg) => {
    // TODO something
})

In addition to the above method that requires main process redirection, there is another way to realize direct communication between rendering processes:

// main process
// Two windows get each other's window id and send it to the rendering processconst { BrowserWindow} = require('electron');

let win1 = new BrowserWindow({...});
let win2 = new BrowserWindow({...});

('distributeIds',{
    win2Id : 
});
('distributeIds',{
    win1Id : 
});
// renderer process
const { remote } = require('electron').remote;

// fromId() can find the target window according to the window id(win2Id).('msg', data);

This is the end of this article about the implementation of Electron inter-process communication. For more related contents of Electron inter-process communication, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!