干巴爹兔的博客 干巴爹兔的博客
首页
  • 前端文章

    • JavaScript
    • HTML
    • Vue
  • 学习笔记

    • JavaScript教程
    • React学习笔记
    • Electron学习笔记
  • 开源项目

    • cloud-app-admin
    • 下班了吗Vscode插件
    • Subversion变更单插件
  • Server

    • Django
  • 学习笔记

    • MySQL学习笔记
  • 运维

    • 服务器部署
    • Linux
  • 日常学习

    • 学习方法
关于
收藏
友链
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

干巴爹兔

卑微的前端打工人
首页
  • 前端文章

    • JavaScript
    • HTML
    • Vue
  • 学习笔记

    • JavaScript教程
    • React学习笔记
    • Electron学习笔记
  • 开源项目

    • cloud-app-admin
    • 下班了吗Vscode插件
    • Subversion变更单插件
  • Server

    • Django
  • 学习笔记

    • MySQL学习笔记
  • 运维

    • 服务器部署
    • Linux
  • 日常学习

    • 学习方法
关于
收藏
友链
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • Electron基础

    • 处识Electron
    • 线程与进程
    • BrowserWindow
    • 进程间的通讯
      • 为什么需要通讯
      • 使用IPC进行通信
      • 使用remote模块实现跨进程访问
  • Electron踩坑

  • 《Electron学习笔记》
  • Electron基础
干巴爹兔
2022-09-20
目录

进程间的通讯

# 为什么需要通讯

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

在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

主进程使用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

这时候可以在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

# 使用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

在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

编辑 (opens new window)
上次更新: 2022/09/20, 17:39:44
BrowserWindow
使用Vite+Ts+Vue3开发Electron的几个坑

← BrowserWindow 使用Vite+Ts+Vue3开发Electron的几个坑→

最近更新
01
使用Vscode开发一个小插件
10-21
02
Vscode插件配置项监听
10-18
03
使用has属性构造必填效果
10-14
更多文章>
Theme by Vdoing | Copyright © 2020-2023 互联网ICP备案: 闽ICP备18027236号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式