 进程间的通讯
进程间的通讯
  # 为什么需要通讯
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
