La communication inter-processus
La communication inter-processus (IPC) est un Ă©lĂ©ment clĂ© de la crĂ©ation dâapplications de bureau avec Electron. Ătant donnĂ© que les processus principaux et de rendu ont des responsabilitĂ©s distinctes au sein du modĂšle de processus dâElectron, IPC est l'unique moyen dâeffectuer un grand nombre de tĂąches courantes, telles que lâappel dâune API native Ă partir de votre interface utilisateur ou le dĂ©clenchement de modifications de votre contenu Web Ă partir de menus natifs.
Les Canaux IPCâ
In Electron, processes communicate by passing messages through developer-defined "channels" with the ipcMain
and ipcRenderer
modules. Le nom de ces canaux est arbitraire (vous pouvez les nommer comme vous voulez) et peut ĂȘtre utilisĂ© de façon bidirectionnelle (vous pouvez utiliser le mĂȘme nom de canal pour les deux modules).
Dans ce guide, nous allons passer en revue quelques modĂšles IPC fondamentaux avec des exemples concrets pouvant ĂȘtre utilisĂ©s comme rĂ©fĂ©rence lors du codage de votre application.
Comprendre les processus isolĂ©s du contexteâ
Before proceeding to implementation details, you should be familiar with the idea of using a preload script to import Node.js and Electron modules in a context-isolated renderer process.
- For a full overview of Electron's process model, you can read the process model docs.
- For a primer into exposing APIs from your preload script using the
contextBridge
module, check out the context isolation tutorial.
ScĂ©nario1 : Moteur de rendu vers le processus principal (unidirectionnel)â
To fire a one-way IPC message from a renderer process to the main process, you can use the ipcRenderer.send
API to send a message that is then received by the ipcMain.on
API.
Vous utiliserez gĂ©nĂ©ralement ce scĂ©nario pour appeler une API du processus principal Ă partir de votre contenu web. Nous allons le dĂ©montrer en crĂ©ant une application simple qui peut modifier par programme le titre de sa fenĂȘtre.
Pour cette démo, vous devrez ajouter du code à votre processus principal, à votre processus de rendu et à un script de préchargement . Le code complet est ci-dessous, cependant nous détaillerons chaque fichier individuellement dans les sections suivantes.
- main.js
- preload.js
- index.html
- renderer.js
const { app, BrowserWindow, ipcMain } = require('electron/main')
const path = require('node:path')
function handleSetTitle (event, title) {
const webContents = event.sender
const win = BrowserWindow.fromWebContents(webContents)
win.setTitle(title)
}
function createWindow () {
const mainWindow = new BrowserWindow({
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
mainWindow.loadFile('index.html')
}
app.whenReady().then(() => {
ipcMain.on('set-title', handleSetTitle)
createWindow()
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})
const { contextBridge, ipcRenderer } = require('electron/renderer')
contextBridge.exposeInMainWorld('electronAPI', {
setTitle: (title) => ipcRenderer.send('set-title', title)
})
<!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'">
<title>Hello World!</title>
</head>
<body>
Title: <input id="title"/>
<button id="btn" type="button">Set</button>
<script src="./renderer.js"></script>
</body>
</html>
const setButton = document.getElementById('btn')
const titleInput = document.getElementById('title')
setButton.addEventListener('click', () => {
const title = titleInput.value
window.electronAPI.setTitle(title)
})
1. Listen for events with ipcMain.on
â
In the main process, set an IPC listener on the set-title
channel with the ipcMain.on
API:
const { app, BrowserWindow, ipcMain } = require('electron')
const path = require('node:path')
// ...
function handleSetTitle (event, title) {
const webContents = event.sender
const win = BrowserWindow.fromWebContents(webContents)
win.setTitle(title)
}
function createWindow () {
const mainWindow = new BrowserWindow({
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
mainWindow.loadFile('index.html')
}
app.whenReady().then(() => {
ipcMain.on('set-title', handleSetTitle)
createWindow()
})
// ...
The above handleSetTitle
callback has two parameters: an IpcMainEvent structure and a title
string. Chaque fois quâun message passe par le canal set-title
, cette fonction extrait lâinstance BrowserWindow attachĂ©e Ă lâexpĂ©diteur du message et lui applique lâAPI win.setTitle
.
Assurez-vous de charger les points d'entrée index.html
et preload.js
pour les étapes suivantes !
2. Exposition de ipcRenderer.send
via le prĂ©chargementâ
Pour envoyer des messages Ă lâĂ©couteur créé ci-dessus, vous pouvez utiliser lâAPI ipcRenderer.send
. Par dĂ©faut, le processus de rendu nâa pas dâaccĂšs aux modules de Node.js et d'Electron. En tant que dĂ©veloppeur dâapplications, vous devez choisir les API Ă exposer Ă partir de votre script de prĂ©chargement Ă lâaide de lâAPI contextBridge
.
Pour ce faire, ajoutez le code suivant dans votre script de préchargement et ainsi vous exposerez à votre processus de rendu la variable globale window.electronAPI
.
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('electronAPI', {
setTitle: (title) => ipcRenderer.send('set-title', title)
})
Ă ce stade, vous pourrez utiliser la fonction window.electronAPI.setTitle()
dans le processus de rendu.
We don't directly expose the whole ipcRenderer.send
API for security reasons. Assurez-vous de limiter autant que possible lâaccĂšs du moteur de rendu aux API Electron.
3. GĂ©nĂ©rer lâinterface utilisateur du processus de renduâ
Vous allez maintenant ajoutez une interface utilisateur de base composĂ©e dâun input de type text et dâun bouton dans le fichier HTML chargĂ© par notre BrowserWindow's:
<!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'">
<title>Hello World!</title>
</head>
<body>
Title: <input id="title"/>
<button id="btn" type="button">Set</button>
<script src="./renderer.js"></script>
</body>
</html>
Afin de rendre ces éléments interactifs, nous allons ajouter quelques lignes de code dans le fichier importé renderer.js
qui tirera parti de la fonctionnalité window.electronAPI
exposée depuis le script de préchargement :
const setButton = document.getElementById('btn')
const titleInput = document.getElementById('title')
setButton.addEventListener('click', () => {
const title = titleInput.value
window.electronAPI.setTitle(title)
})
Ă ce stade, votre dĂ©mo devrait ĂȘtre entiĂšrement fonctionnelle. Essayez dâutiliser le champ de saisie et voyez ce quâil advient du titre de votre BrowserWindow !
ScĂ©nario2 : Moteur de rendu vers le processus principal (bidirectionnel)â
Une application courante d'IPC bidirectionnel est l'appel d'un module du processus principal à partir du code de votre processus de rendu avec l'attente d'un résultat. This can be done by using ipcRenderer.invoke
paired with ipcMain.handle
.
Dans lâexemple suivant, nous allons ouvrir une boĂźte de dialogue native d'ouverture de fichier Ă partir du processus de rendu et retourner le chemin dâaccĂšs du fichier sĂ©lectionnĂ©.
Pour cette démo, vous devrez ajouter du code à vos processus principal et processus de rendu et à un script de préchargement . Le code complet est ci-dessous, cependant nous détaillerons chaque fichier individuellement dans les sections suivantes.
- main.js
- preload.js
- index.html
- renderer.js
const { app, BrowserWindow, ipcMain, dialog } = require('electron/main')
const path = require('node:path')
async function handleFileOpen () {
const { canceled, filePaths } = await dialog.showOpenDialog()
if (!canceled) {
return filePaths[0]
}
}
function createWindow () {
const mainWindow = new BrowserWindow({
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
mainWindow.loadFile('index.html')
}
app.whenReady().then(() => {
ipcMain.handle('dialog:openFile', handleFileOpen)
createWindow()
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})
const { contextBridge, ipcRenderer } = require('electron/renderer')
contextBridge.exposeInMainWorld('electronAPI', {
openFile: () => ipcRenderer.invoke('dialog:openFile')
})
<!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'">
<title>Dialog</title>
</head>
<body>
<button type="button" id="btn">Open a File</button>
File path: <strong id="filePath"></strong>
<script src='./renderer.js'></script>
</body>
</html>
const btn = document.getElementById('btn')
const filePathElement = document.getElementById('filePath')
btn.addEventListener('click', async () => {
const filePath = await window.electronAPI.openFile()
filePathElement.innerText = filePath
})
1. Ăcoute des Ă©vĂ©nements avec ipcMain.handle
â
Dans le processus principal, nous allons créer une fonction handleFileOpen()
qui appelle
dialog. howOpenDialog
et retourne le chemin du fichier sélectionné par l'utilisateur. Cette fonction est utilisée comme callback chaque fois qu'un message ipcRender.invoke
est envoyé par le canal dialog:openFile
depuis le processus de rendu. La valeur de retour est ensuite renvoyĂ©e sous forme de promesse Ă lâappel « invoke »
dâorigine.
Les erreurs gĂ©nĂ©rĂ©es par 'handle' dans le processus principal ne sont pas transparentes puisqu'elles sont sĂ©rialisĂ©es et que seule la propriĂ©tĂ© 'message' de lâerreur dâorigine est fournie au processus de rendu. Pour plus de dĂ©tails, veuillez vous rĂ©fĂ©rer au problĂšme #24427 sur github .
const { app, BrowserWindow, dialog, ipcMain } = require('electron')
const path = require('node:path')
// ...
async function handleFileOpen () {
const { canceled, filePaths } = await dialog.showOpenDialog({})
if (!canceled) {
return filePaths[0]
}
}
function createWindow () {
const mainWindow = new BrowserWindow({
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
mainWindow.loadFile('index.html')
}
app.whenReady().then(() => {
ipcMain.handle('dialog:openFile', handleFileOpen)
createWindow()
})
// ...
Le préfixe dialog:
du nom de canal IPC nâa aucun effet sur le code. Il ne sert que dâespace de nommage afin d'apporter plus de lisibilitĂ© au code.
Assurez-vous de charger les points d'entrée index.html
et preload.js
pour les étapes suivantes !
2. Exposition de ipcRenderer.invoke
via le prĂ©chargementâ
Dans le script de préchargement, nous exposons une fonction mono-ligne openFile
appellant et renvoyant la valeur de ipcRenderer.invoke('dialog:openFile')
. Nous utiliserons cette API à l'étape suivante pour appeler la boßte de dialogue native à partir de l'interface utilisateur de notre moteur de rendu.
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('electronAPI', {
openFile: () => ipcRenderer.invoke('dialog:openFile')
})
We don't directly expose the whole ipcRenderer.invoke
API for security reasons. Veillez toujours Ă limiter autant que possible lâaccĂšs du moteur de rendu aux API Electron.
3. GĂ©nĂ©rer lâinterface utilisateur du processus de renduâ
Enfin, pour termier, construisons le fichier HTML qui sera chargé dans notre BrowserWindow.
<!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'">
<title>Dialog</title>
</head>
<body>
<button type="button" id="btn">Open a File</button>
File path: <strong id="filePath"></strong>
<script src='./renderer.js'></script>
</body>
</html>
Lâinterface utilisateur se compose dâun seul Ă©lĂ©ment #btn
button qui sera utilisé pour déclencher notre API de préchargement, et l'élément d'id #filePath
qui sera utilisĂ© pour afficher le chemin dâaccĂšs du fichier sĂ©lectionnĂ©. Pour que ces Ă©lĂ©ments fonctionnent, il ne faut que quelques lignes de code dans le script du processus de rendu :
const btn = document.getElementById('btn')
const filePathElement = document.getElementById('filePath')
btn.addEventListener('click', async () => {
const filePath = await window.electronAPI.openFile()
filePathElement.innerText = filePath
})
Dans le snippet ci-dessus, nous écoutons les clics du bouton #btn
, et appelons notre API window.electronAPI.openFile()
pour activer la boĂźte de dialogue native d'Ouverture d'un fichier. Nous affichons ensuite le chemin dâaccĂšs au fichier sĂ©lectionnĂ© dans lâĂ©lĂ©ment #filePath
.
Remarque : mĂ©thodes plus anciennesâ
LâAPI ipcRenderer.invoke
a été ajoutée dans Electron 7 apportant un moyen convivial aux développeurs pour régler les problÚmes d'IPC bidirectionnel à partir du processus de rendu. However, a couple of alternative approaches to this IPC pattern exist.
Nous vous recommandons dâutiliser ipcRenderer.invoke
chaque fois que possible. Les modÚles d'échange bidirectionnel suivants ne sont documentés qu'à des fins historiques.
Dans les exemples suivants, nous appelons ipcRenderer
directement à partir du script de préchargement pour que les échantillons de code ne soient pas trop volumineux.
Utilisation de ipcRenderer.send
â
LâAPI ipcRenderer.send
que nous avons utilisĂ©e pour la communication unidirectionnelle peut Ă©galement ĂȘtre exploitĂ©e pour effectuer une communication bidirectionnelle. CâĂ©tait d'ailleurs la mĂ©thode recommandĂ©e pour la communication bidirectionnelle asynchrone via IPC avant Electron7.
// Vous pouvez également placer ce code dans le processus de rendu
// avec l'API `contextBridge`
const { ipcRenderer } = require('electron')
ipcRenderer. n('asynchronous-reply', (_event, arg) => {
console.log(arg) // affiche "pong" dans la console DevTools
})
ipcRenderer.send('asynchronous-message', 'ping')
ipcMain.on('asynchronous-message', (event, arg) => {
console.log(arg) // prints "ping" in the Node console
// works like `send`, but returning a message back
// to the renderer that sent the original message
event.reply('asynchronous-reply', 'pong')
})
Mais cette approche présente certains inconvénients :
- Vous devez configurer un second écouteur
ipcRenderer.on
pour gérer la réponse dans le processus de rendu . Alors qu'avecinvoke
, vous obtenez en retour une Promise de l'appel API original. - Il nây a pas de moyen Ă©vident de jumeler le message
asynchronous-reply
Ă celui de l'asynchronous-message
dâorigine. Si vous avez des messages trĂšs frĂ©quents qui vont et viennent via ces canaux, vous devrez ajouter du code supplĂ©mentaire pour suivre individuellement chaque appel et rĂ©ponse.
Utilisation de ipcRenderer.sendSync
â
LâAPI ipcRenderer.sendSync
envoie un message au processus principal et attend de maniÚre synchrone une réponse .
const { ipcMain } = require('electron')
ipcMain.on('synchronous-message', (event, arg) => {
console.log(arg) // affiche "ping" dans la console Node
event.returnValue = 'pong'
})
// Vous pouvez également placer ce code dans le processus de rendu
// avec l'API `contextBridge`
const { ipcRenderer } = require('electron')
const result = ipcRenderer.sendSync('synchronous-message', 'ping')
console.log(result) // affiche "pong" dans la console des DevTools
La structure de ce code est trĂšs similaire au modĂšle invoke
, mais nous recommandons d'Ă©viter cette API pour des raisons de performances. Sa nature synchrone fait que le processus de rendu sera bloquĂ© jusquâĂ la rĂ©ception dâune rĂ©ponse.
ScĂ©nario 3 : Processus principal vers moteur de renduâ
Lorsque vous envoyez un message du processus principal à un processus de rendu, vous devez spécifier le moteur de rendu destinataire de ce message. Messages need to be sent to a renderer process via its WebContents
instance. This WebContents instance contains a send
method that can be used in the same way as ipcRenderer.send
.
Pour illustrer ce scĂ©nario, nous allons crĂ©er un compteur contrĂŽlĂ© par le menu natif du systĂšme dâexploitation.
Pour cette démo, vous devrez ajouter du code à votre processus principal, à votre processus de rendu et à un script de préchargement . Le code complet est ci-dessous, cependant nous détaillerons chaque fichier individuellement dans les sections suivantes.
- main.js
- preload.js
- index.html
- renderer.js
const { app, BrowserWindow, Menu, ipcMain } = require('electron/main')
const path = require('node:path')
function createWindow () {
const mainWindow = new BrowserWindow({
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
const menu = Menu.buildFromTemplate([
{
label: app.name,
submenu: [
{
click: () => mainWindow.webContents.send('update-counter', 1),
label: 'Increment'
},
{
click: () => mainWindow.webContents.send('update-counter', -1),
label: 'Decrement'
}
]
}
])
Menu.setApplicationMenu(menu)
mainWindow.loadFile('index.html')
// Open the DevTools.
mainWindow.webContents.openDevTools()
}
app.whenReady().then(() => {
ipcMain.on('counter-value', (_event, value) => {
console.log(value) // will print value to Node console
})
createWindow()
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})
const { contextBridge, ipcRenderer } = require('electron/renderer')
contextBridge.exposeInMainWorld('electronAPI', {
onUpdateCounter: (callback) => ipcRenderer.on('update-counter', (_event, value) => callback(value)),
counterValue: (value) => ipcRenderer.send('counter-value', value)
})
<!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'">
<title>Menu Counter</title>
</head>
<body>
Current value: <strong id="counter">0</strong>
<script src="./renderer.js"></script>
</body>
</html>
const counter = document.getElementById('counter')
window.electronAPI.onUpdateCounter((value) => {
const oldValue = Number(counter.innerText)
const newValue = oldValue + value
counter.innerText = newValue.toString()
window.electronAPI.counterValue(newValue)
})
1. Envoie de messages avec le module 'webContents'â
Pour cette dĂ©mo, nous devrons dâabord crĂ©er un menu personnalisĂ© dans le processus principal Ă lâaide du module 'Menu' dâElectron celui-ci utilisera lâAPI 'webContents.send' pour envoyer un message IPC du processus principal au moteur de rendu cible .
const { app, BrowserWindow, Menu, ipcMain } = require('electron')
const path = require('node:path')
function createWindow () {
const mainWindow = new BrowserWindow({
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
const menu = Menu.buildFromTemplate([
{
label: app.name,
submenu: [
{
click: () => mainWindow.webContents.send('update-counter', 1),
label: 'Increment'
},
{
click: () => mainWindow.webContents.send('update-counter', -1),
label: 'Decrement'
}
]
}
])
Menu.setApplicationMenu(menu)
mainWindow.loadFile('index.html')
}
// ...
Pour les besoins du tutoriel, il est important de noter que le gestionnaire de click
envoie un message ( 1
ou -1
) au processus de rendu via le canal update-counter
.
click: () => mainWindow.webContents.send('update-counter', -1)
Assurez-vous de charger les points d'entrée index.html
et preload.js
pour les étapes suivantes !
2. Exposition de ipcRenderer.on
via le prĂ©chargementâ
Comme dans lâexemple prĂ©cĂ©dent du moteur de rendu vers le processus principal, nous allons utiliser les modules contextBridge
et ipcRenderer
dans le script de préchargement pour exposer la fonctionnalité IPC au processus de rendu :
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('electronAPI', {
onUpdateCounter: (callback) => ipcRenderer.on('update-counter', (_event, value) => callback(value))
})
AprĂšs avoir chargĂ© le script de prĂ©chargement, votre processus de rendu aura accĂšs Ă la fonction dâĂ©couteur window.electronAPI.onUpdateCounter()
.
We don't directly expose the whole ipcRenderer.on
API for security reasons. Assurez-vous de limiter autant que possible lâaccĂšs du moteur de rendu aux API Electron. Also don't just pass the callback to ipcRenderer.on
as this will leak ipcRenderer
via event.sender
. Use a custom handler that invoke the callback
only with the desired arguments.
Dans le cadre de cet exemple minimal, vous pouvez appeler ipcRenderer.on
directement dans le script de prĂ©chargement plutĂŽt que de lâexposer via le contextBridge.
const { ipcRenderer } = require('electron')
window.addEventListener('DOMContentLoaded', () => {
const counter = document.getElementById('counter')
ipcRenderer.on('update-counter', (_event, value) => {
const oldValue = Number(counter.innerText)
const newValue = oldValue + value
counter.innerText = newValue
})
})
Toutefois, cette approche n'est pas trĂšs flexible par rapport Ă lâexposition de vos API de prĂ©chargement par contextBridge, car votre Ă©couteur ne peut pas interagir directement avec le code de votre moteur de rendu.
3. GĂ©nĂ©rer lâinterface utilisateur du processus de renduâ
Pour lier le tout, nous allons créer une interface dans le fichier HTML chargé qui contient un élément d'id #counter
que nous utiliserons pour afficher les valeurs:
<!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'">
<title>Menu Counter</title>
</head>
<body>
Current value: <strong id="counter">0</strong>
<script src="./renderer.js"></script>
</body>
</html>
Enfin, pour mettre Ă jour les valeurs dans le document HTML, nous allons ajouter quelques lignes de manipulation du DOM afin que la valeur de lâĂ©lĂ©ment #counter
soit mise à jour chaque fois que nous lançons un événement update-counter
.
const counter = document.getElementById('counter')
window.electronAPI.onUpdateCounter((value) => {
const oldValue = Number(counter.innerText)
const newValue = oldValue + value
counter.innerText = newValue.toString()
})
Dans le code ci-dessus, nous passons une callback Ă la fonction window.electronAPI.onUpdateCounter
exposée à partir de notre script de préchargement. Le deuxiÚme paramÚtre value
correspond au 1
ou au -1
que nous passions Ă partir de lâappel webContents.send
du menu natif.
Facultatif : retourner une rĂ©ponseâ
Il nây a pas dâĂ©quivalent au ipcRenderer.invoke
pour un IPC du processus principal vers un processus de rendu. Au lieu de cela, vous pouvez renvoyer une réponse au processus principal à partir de la callback avec ipcRenderer.on
.
Nous pouvons en faire la dĂ©monstration en modifiant lĂ©gĂšrement le code de lâexemple prĂ©cĂ©dent. In the renderer process, expose another API to send a reply back to the main process through the counter-value
channel.
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('electronAPI', {
onUpdateCounter: (callback) => ipcRenderer.on('update-counter', (_event, value) => callback(value)),
counterValue: (value) => ipcRenderer.send('counter-value', value)
})
const counter = document.getElementById('counter')
window.electronAPI.onUpdateCounter((value) => {
const oldValue = Number(counter.innerText)
const newValue = oldValue + value
counter.innerText = newValue.toString()
window.electronAPI.counterValue(newValue)
})
Dans le processus principal, écoutez les événements counter-value
et gérez-les de maniÚre appropriée.
// ...
ipcMain.on('counter-value', (_event, value) => {
console.log(value) // affichera la valeur dans la console Node
})
// ...
ScĂ©nario 4 : Echange entre deux moteurs de renduâ
Avec Electron, Il nây a pas, Ă lâaide des modules ipcMain
et ipcRenderer
, de moyen direct pour transmettre des messages entre des processus de rendu . Pour y parvenir, vous avez deux options :
- Utiliser le processus principal comme agent de messagerie entre les moteurs de rendu. Cela impliquera lâenvoi dâun message dâun moteur de rendu au processus principal, qui devra transmettre ce message Ă lâautre moteur de rendu.
- Pass a MessagePort from the main process to both renderers. Ceci permettra, aprĂšs la configuration initiale, une communication directe entre les moteurs de rendu.
SĂ©rialisation dâobjetsâ
LâimplĂ©mentation IPC dâElectron utilisant la norme HTML Structured Clone Algorithm pour sĂ©rialiser les objets transmis entre les processus, implique que seuls certains types dâobjets pourront ĂȘtre transmis via les canaux IPC.
En particulier, les objets DOM (par exemple, Element
, Location
et DOMMatrix
), les objets de Node.js s'appuyant sur des classes C++ (par exemple, process.env
, certains membres de Stream
) et les objets Electron s'appuyant également sur des classes C++ (par exemple, WebContents
, BrowserWindow
et WebFrame
) ne sont pas sérialisables avec Structured Clone.