I wrote a special article referring to the electron Chinese official website and adding my own understanding. If you feel like it, please give a thumbs up or follow it. Please leave a comment and point out question A on wechat public account: [Daily Life of Cat 12]
Electron communication
- Use 'ipcMain' and 'ipcRenderer' modules - use the electron. Remote moduleCopy the code
We will now focus on the first method of communication
Understand the main and renderer processes
Main Process
- A electron can only have one main process
- The main process means that after you run the electron. Command, the specified file in main under the package.json file in the corresponding current directory will be executed
- The interface associated with creating a GUI(similar to creating a window) can only be called through the main process.Copy the code
Renderer Process
- Pages created by the main process calling the GUI interface have their own process, called the renderer. The main process instantiates BrowserWindow. Each BrowserWindow instance renders a Web page, independently of each other. When a BrowserWindow is destroyed, the corresponding rendering process is terminated.
- Renderers are managed by the main process, each independent of the other and managing only their own Web pages
If they need to communicate, they need to communicate with IPC
The ipc communication
In electron, we need the Main Process and the Renderer Process to communicate, using two modules
-
ipcMain
Asynchronous communication from the main process to the renderer. IpcMain is an instance of EventEmitter. When used in the main process, it handles asynchronous and synchronous information sent from the renderer process (web page). Messages sent from the renderer process will be sent to this module.
-
ipcRenderer
Asynchronous communication from the renderer process to the main process. IpcRenderer is an instance of EventEmitter. You can use some of the methods it provides to send synchronous or asynchronous messages from the renderer (web page) to the main process. It can also receive messages returned by the main process.
Relevant methods of IPC communication
The method by which the renderer communicates with the main process
Directory preparation, modification and deletion are all in these few file operations
├─ ├─ ├─ ├─ ├─ ├─ ├─ ├─ index.html // web-pageCopy the code
index.html
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0">
<title>2020-01-08</title>
</head>
<body>Electron communication demonstration<script src="./renderer.js"></script>// Import js externally</body>
</html>
Copy the code
main.js
const { app, BrowserWindow, ipcMain } = require("electron");
function createWindow() {
const win = new BrowserWindow({
width: 1920.height: 1080.webPreferences: {
nodeIntegration: true.contextIsolation: false,}}); win.webContents.openDevTools();// Open the debugging tool
win.loadFile("index.html");
}
app.whenReady().then(createWindow);
app.on("window-all-closed".() = > {
if(process.platform ! = ="darwin") { app.quit(); }}); app.on("activate".() = > {
if (BrowserWindow.getAllWindows().length === 0) { createWindow(); }}); ipcMain.on("async-message".(event, arg) = > {
// Asynchronous message reply
console.log('async-message: I received an asynchronous message', arg);
event.reply("async-reply"."Dude, I got a message. - It's asynchronous.");
});
ipcMain.on("sync-message".(event, arg) = > {
// Synchronize message reply
console.log('async-message: I received a synchronous message', arg);
event.returnValue = "Dude, I got a message. - From sync.";
});
Copy the code
renderer.js
const { ipcRenderer } = require("electron");
// Synchronize messages
let message = ipcRenderer.sendSync("sync-message"."Send a synchronous message.");
console.log("Synchronize messages :", message);
// Asynchronous messages
ipcRenderer.on("async-reply".(event, arg) = > {
console.log("Asynchronous message :", arg);
});
ipcRenderer.send("async-message"."Send an asynchronous message.");
Copy the code
package.json
{
"name": "2020-01-08"."version": "1.0.0"."description": ""."main": "main.js"."scripts": {
"start": "electron ."
},
"keywords": []."author": ""."license": "ISC"."devDependencies": {
"electron": "^ 11.1.1." "}}Copy the code
The results of
Electron (main process)
Async-message: I received a synchronous message send a synchronous message async-message: I received an asynchronous message send an asynchronous messageCopy the code
Client (renderer)
Synchronous message: dude I got a message - from synchronous asynchronous message: dude I got a message - from asynchronousCopy the code
This section will modify and operate based on these files
For the above content mainly used several methods to achieve the rendering process to the main process communication
Ipcmain. on(Channel, Listener) The main process listens for communication from the renderer. IpcMain is an instance of EventEmitter
-
Channel Specifies the name of the event to listen on, of type String
-
The listener listens to a callback that has two input arguments
-
Event IpcMainEvent Indicates the IPC event
Event There are two types of messages that need to be replied. One is asynchronous reply and the other is synchronous reply
- This parameter is required when synchronizing messages are returned
event.returnValue
. event.reply(...)
Send an asynchronous message back to the sender- Both are shown in the demo above
- This parameter is required when synchronizing messages are returned
-
. Args any[] are all input arguments passed by the client
-
The IpcMainEvent inherited Event has the following attribute values
- ProcessId (type Integer) The internal ID of the renderer process that sent this message
- FrameId Integer Type) The ID of the renderer frame from which the message was sent (possibly iframe)
- ReturnValue (type any)) sets it to the value to be returned in the synchronization message
- Reply (Function type) the Function that sends an IPC message to the renderer framework, which sends the original message that is currently being processed. You should use the “reply” method to reply to sent messages to ensure that the reply will go to the correct process and framework.
channel
String. args
any[]
**ipcRenderer.sendSync(channel, … Args) ** The renderer sends synchronization messages to the main process
- Channel Indicates the event name. The value is a String
- . args any[]
Return any – the value sent by the ipcMain handler.
Sending synchronous messages will block the renderer’s rendering process, similar to async await mode, and it is better to choose the asynchronous version of processing
ipcRenderer.send(channel, … Args), the renderer sends an asynchronous message to the main process
- Channel Indicates the event name. The value is a String
- . args any[]
All args parameters above can only be serialized strings, all functions, Promise, Symbol, weakMaps, weakSets will throw exceptions,DOM node in electron9 will also throw exceptions
Other functions
Only listen for one event
ipcMain.once(channel, listener)
-
Channel Specifies the name of the event to listen on, of type String
-
The listener listens to a callback that has two input arguments
-
Event IpcMainEvent Indicates the IPC event
Event There are two types of messages that need to be replied. One is asynchronous reply and the other is synchronous reply
- This parameter is required when synchronizing messages are returned
event.returnValue
. event.reply(...)
Send an asynchronous message back to the sender- Both are shown in the demo above
- This parameter is required when synchronizing messages are returned
-
. Args any[] are all input arguments passed by the client
-
This event function will only listen once and will be removed after listening
Use ipcMain. On listening
# main.js
// Normal listener reply
ipcMain.on("on-message".(event, arg) = > {
event.reply("on-reply-message", arg);
});
# renderer.js
for (let index = 0; index < 5; index++) {
ipcRenderer.send("on-message".The first `${index}Time `);
}
ipcRenderer.on("on-reply-message".(event, arg) = > {
console.log(` reply:${arg}`);
});
/ / the resultResponse: the first0First reply: No1First reply: No2First reply: No3timeCopy the code
Use ipcMain. Once to monitor
# main.js
ipcMain.once("one-message".(event, arg) = > {
event.reply("one-reply-message", arg);
});
# renderer.js
for (let index = 0; index < 5; index++) {
ipcRenderer.send("one-message".The first `${index}Time `);
}
ipcRenderer.on("one-reply-message".(event, arg) = > {
console.log(` reply:${arg}`);
});
/ / the resultResponse: the first0timeCopy the code
ipcRenderer.once(channel, listener)
- The method is similar to on event listeningCopy the code
This method also listens for only one message from the main process and automatically removes the event
# main.js
ipcMain.on("one-message".(event, arg) = > {
event.reply("one-reply-message", arg);
});
# renderer.js
for (let index = 0; index < 5; index++) {
ipcRenderer.send("one-message".The first `${index}Time `);
}
ipcRenderer.once("one-reply-message".(event, arg) = > {
console.log(` reply:${arg}`);
});
/ / the resultResponse: the first0timeCopy the code
Remove listening events
The ipcmain. removeListener(channel, listener) parameter is removed only if it matches the defined listener function
# main.js
function callback(event, arg) {
event.reply("reply".'The main process returns a message:${arg}`);
}
ipcMain.on("message", callback);
ipcMain.removeListener("message", callback);
# renderer.js
function watcher(event, arg) {
console.log(arg);
}
ipcRenderer.send("message"."Render process sends message");
ipcRenderer.on("reply", watcher);
/ / the result
空
Copy the code
ipcMain.removeAllListeners([channel])
- channel removes all listeners of this eventCopy the code
# main.js
function callback(event, arg) {
event.reply("reply".'The main process returns a message:${arg}`);
}
ipcMain.on("message", callback);
ipcMain.removeAllListeners("message");// The specified event
//ipcMain.removeAllListeners(); // All events are removed
# renderer.js
function watcher(event, arg) {
console.log(arg);
}
ipcRenderer.send("message"."Render process sends message");
ipcRenderer.on("reply", watcher);
/ / the result
空
Copy the code
Asynchronous back and forth communication
The main change is to process the returned results like returning promse, so the input parameters are basically the same
Ipcmain. handle(channel, listener) Listener function of the main process
ipcRenderer.invoke(channel, … Args) the message sending function of the renderer process
# main.js
ipcMain.handle("message".async(event, ... args) => {let someMessage = await Promise.resolve("I am an asynchronous message back.");
return someMessage;
});
# renderer.js
(async() = > {let result = await ipcRenderer.invoke("message");
console.log(result); }) ();/ / the resultI am asynchronously returning the messageCopy the code
Ipcmain. handleOnce(channel, listener) a single execution
# main.js
ipcMain.handleOnce("message".async(event, ... args) => {let someMessage = await Promise.resolve("I am an asynchronous message back.");
return someMessage;
});
# renderer.js
(async() = > {let result = await ipcRenderer.invoke("message");
console.log(result); }) ();/ / the resultI am asynchronously returning the messageCopy the code
** ipcmain.removeHandler (channel)** Removes listener functions
# main.js
ipcMain.handle("message".async(event, ... args) => {let someMessage = await Promise.resolve("I am an asynchronous message back.");
return someMessage;
});
ipcMain.removeHandler("message"); // Be sure to write remove that event name
# renderer.js
(async() = > {let result = await ipcRenderer.invoke("message");
console.log(result); }) ();/ / the resultAn errorCopy the code
Use webworkers to pass information
Ipcrenderer. postMessage(channel, message, [Transfer]) this function is similar to webworker in web pages. Baidu has not found its usage in electron. I wrote a set that seems to be able to pass messages according to webwork (to be corrected)
# main.js
ipcMain.on("port".(e, msg) = > {
const [port] = e.ports;
console.log(port, msg, e.ports);
port.postMessage("Send a message to the render process");
});
# renderer.js
const { port1, port2 } = new MessageChannel();
ipcRenderer.postMessage("port", { message: "hello" }, [port2]);
port1.onmessage = (arg) = > {
console.log(arg.data);
};
/ / the resultSend a message to the rendererCopy the code
We’re basically talking about renderers sending messages to the main process and getting a response, but in practice, we also have each render process communicating with each other, and the main process communicating with one render process
If you think my article is ok, click a like or follow the next, there are wonderful stories waiting for you oh, but also can cloud masturbation cat