进程间的通讯
# 为什么需要通讯
Electron
使用 IPC (interprocess communication)
在进程之间进行通讯,主进程有渲染进程做不到的能力,他们能使用的API也是完全不一样的。主进程需要通知渲染进程更新,同时渲染进程在进行点击操作时需要主进程进行应用消息通知,所以他们需要沟通。Electron的通知类似于DOM
的事件机制,它的底层是基于NodeJS
的Emiter
实例构造。
# 使用IPC进行通信
首先在index.html
中定义一个button
按钮和显示消息的span
标签
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'">
<link href="./styles.css" rel="stylesheet">
<title>Hello World!</title>
</head>
<body>
<h1>Hello World!</h1>
We are using Node.js <span id="node-version"></span>
<button id="send">Send To Main</button>
<span id="message"></span>
<!-- You can also require other files to run in this process -->
<script src="./renderer.js"></script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
在renderer.js
中使用ipcRenderer
方法发送事件给主进程
// This file is required by the index.html file and will
// be executed in the renderer process for that window.
// No Node.js APIs are available in this process because
// `nodeIntegration` is turned off. Use `preload.js` to
// selectively enable features needed in the rendering
// process.
const { ipcRenderer } = require('electron')
window.addEventListener('DOMContentLoaded', () => {
document.getElementById('node-version').innerHTML = process.versions.node
document.getElementById('send').addEventListener('click', () => {
ipcRenderer.send('message', 'Hello from renderer')
})
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
主进程使用ipcMain
方法来接受消息,使用回调函数中的event
对象进行消息回复
const { app, BrowserWindow, ipcMain } = require('electron')
app.on('ready', () => {
let mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
}
})
mainWindow.loadFile('index.html')
mainWindow.webContents.openDevTools()
ipcMain.on('message', (event, arg) => {
console.log(arg)
event.reply('reply', 'Hello from main')
})
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
这时候可以在renderer.js
中添加响应的方法
// This file is required by the index.html file and will
// be executed in the renderer process for that window.
// No Node.js APIs are available in this process because
// `nodeIntegration` is turned off. Use `preload.js` to
// selectively enable features needed in the rendering
// process.
const { ipcRenderer } = require('electron')
window.addEventListener('DOMContentLoaded', () => {
document.getElementById('node-version').innerHTML = process.versions.node
document.getElementById('send').addEventListener('click', () => {
ipcRenderer.send('message', 'Hello from renderer')
})
ipcRenderer.on('reply', (event, arg) => {
console.log(arg)
document.getElementById('message').innerHTML = arg
})
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 使用remote
模块实现跨进程访问
先安装remote
模块
npm install --save @electron/remote
1
在 main.js
中配置
const { app, BrowserWindow, ipcMain } = require('electron')
const remote = require('@electron/remote/main')
// 初始化
remote.initialize()
app.on('ready', () => {
let mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
}
})
// 允许窗口的 webcontents 访问
remote.enable(mainWindow.webContents)
mainWindow.loadFile('index.html')
mainWindow.webContents.openDevTools()
ipcMain.on('message', (event, arg) => {
console.log(arg)
event.reply('reply', 'Hello from main')
})
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
在renderer.js
中添加remote
导入
// This file is required by the index.html file and will
// be executed in the renderer process for that window.
// No Node.js APIs are available in this process because
// `nodeIntegration` is turned off. Use `preload.js` to
// selectively enable features needed in the rendering
// process.
const { ipcRenderer } = require('electron')
const { BrowserWindow } = require('@electron/remote')
window.addEventListener('DOMContentLoaded', () => {
document.getElementById('node-version').innerHTML = process.versions.node
document.getElementById('send').addEventListener('click', () => {
ipcRenderer.send('message', 'Hello from renderer')
let win = new BrowserWindow({
width: 400,
height: 300,
})
win.loadURL('https://www.google.com')
})
ipcRenderer.on('reply', (event, arg) => {
console.log(arg)
document.getElementById('message').innerHTML = arg
})
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
编辑 (opens new window)
上次更新: 2022/09/20, 17:39:44