Interprocess communication
When developing applications using Electron, we often need to transfer data between the main process and the renderer process to meet the requirements of the product.
Suppose we now want to make an APP, APP has a window to display the current machine CPU model, total memory and other information. The logic is simple, just take the relevant information and display it in the window. In the Electron rendering process, there is no API directly provided to obtain relevant information, so the main process is used to obtain information and then pass it to the rendering process for display.
To achieve such functionality, we can implement it in the following three ways
- The method call
- Data sharing
- Data messages
Let’s use code examples to illustrate each of these approaches
The main directory structure of the sample program is as follows
├─ ├─ ├─ ├─ download.txt └─ ├─ download.txtCopy the code
The method call
// The main process code is main/ systeminfo.js
var os = require('os');
// Get CPU information
function getCpu(){
var cores = os.cpus();
if(cores.length > 0) {return cores[0].model;
}
}
exports.getCpu = getCpu;
Copy the code
// Render process code renderer/index.js
// We need to get information here that the main process can get
const obj = require('electron').remote.require('./systemInfo')
const cpuInfo = obj.getCpu();
console.log(cpuInfo);
Copy the code
In this example, we use the remote module provided by Electron to require a module that can only be executed by the main process to get the required information. This allows us to display device information in the renderer window. Let’s look at how data sharing is implemented.
Data sharing
The above example uses remote. Require to call the main process method indirectly. In data sharing, instead of calling the method directly, the data is fetched directly from the main process.
// The main process code is main/ systeminfo.js
const os = require('os');
// Get CPU information
function getCpu(){
const cores = os.cpus();
if(cores.length > 0) {return cores[0].model;
}
}
exports.getCpu = getCpu;
Copy the code
// Main process code main/index.js
const getCpu = require('./systemInfo');
const cpuInfo = getCpu();
global['cpuInfo'] = cpuInfo;
Copy the code
// Render process code renderer/index.js
const cpuInfo = require('electron').remote.getGlobal('cpuInfo');
Copy the code
In this example, we fetch information from the systemInfo module in the main process and store the information into the Electron global object. In the rendering process, through the getGlobal method provided by the remote object, we can directly obtain the attribute value in the global object, to achieve the desired function. The disadvantage of this scheme is that the desired information for rendering is processed and stored in the properties of the Global object before fetching, each time fetching a fixed value. In the last example, it was passive, because in the last example, it was an active fetch, and when the value changed, you could get the latest value.
The above two implementation methods are implemented through the remote module, so what is the remote module?
The Remote module is designed specifically by Electorn to enhance the rendering process. It provides methods such as require and getGlobal to obtain information about the main process. When remote calls remote methods and shared variables, you are actually sending synchronous messages. For messages, let’s look at the following example.
Data messages
Again, we need to fetch data in the render process
// The main process code is main/ systeminfo.js
const os = require('os');
// Get CPU information
function getCpu(){
const cores = os.cpus();
if(cores.length > 0) {return cores[0].model;
}
}
exports.getCpu = getCpu;
Copy the code
// Main process code main/index.js
const getCpu = require('./systemInfo');
const ipc = require('electron').ipcMain;
ipc.on('get-cpu-info'.function (event, arg) {
event.sender.send('cpu-info-reply', getCpu())
})
Copy the code
// Render process code renderer/index.js
const ipc = require('electron').ipcRenderer;
const getCpuInfoBtn = document.getElementById('info-btn');
getCpuInfoBtn.addEventListener('click'.function () {
ipc.send('get-cpu-info');
})
ipc.on('cpu-info-reply'.function (event, arg) {
console.log(arg);
})
Copy the code
Instead of using the remote module, we use the IPC module provided by Electron to fulfill the requirements. The IPC module is provided by Electron for the communication between the main process and the renderer process. It is similar to the publishing and subscription of events. The initiator of a message sends an event through the IPC module and listens for the corresponding event at the receiver. At the end of the second example, the remote call actually sends a synchronous message, using the same principle as ipc’s sync message.
In this requirement, it is the renderer process that needs to fetch information from the main process. In some cases, it may be the main process that takes the initiative to fetch messages from the renderer in a similar way, with a change of priority.
conclusion
Two modules involved in communication between the main process and the renderer process
- Remote: Data transfer can be realized through direct method call and global variable acquisition
- Ipc: Data transfer can be realized through event registration and publishing