简介
ipcMain 模块管理主进程到渲染进程的异步通信
ipcRenderer模块管理从渲染器进程到主进程的异步通信。
ipcMain
从主进程到渲染进程的异步通信。
进程:主进程
ipcMain
是一个 EventEmitter 的实例。 当在主进程中使用时,它处理从渲染器进程(网页)发送出来的异步和同步信息。 从渲染器进程发送的消息将被发送到该模块。
EN
发送消息
也可以从主进程向渲染进程发送消息,查阅ebContents.send获取更多信息。
- 发送消息时,事件名称为
channel
。 - 回复同步信息时,需要设置
event.returnValue
。 - 可以使用
event.reply(...)
将异步消息发送回发送者。 This helper method will automatically handle messages coming from frames that aren't the main frame (e.g. iframes) whereasevent.sender.send(...)
will always send to the main frame.
下面是在渲染和主进程之间发送和处理消息的一个例子:
// 在主进程中.
const { ipcMain } = require('electron')
ipcMain.on('asynchronous-message', (event, arg) => {
console.log(arg) // prints "ping"
event.reply('asynchronous-reply', 'pong')
})
ipcMain.on('synchronous-message', (event, arg) => {
console.log(arg) // prints "ping"
event.returnValue = 'pong'
})
//在渲染器进程 (网页) 中。
const { ipcRenderer } = require('electron')
console.log(ipcRenderer.sendSync('synchronous-message', 'ping')) // prints "pong"
ipcRenderer.on('asynchronous-reply', (event, arg) => {
console.log(arg) // prints "pong"
})
ipcRenderer.send('asynchronous-message', 'ping')
EN
方法
IpcMain模块有以下方法来侦听事件:
EN
ipcMain.on(channel, listener)
-
channel
String -
listener
Function
event
IpcMainEvent...args
any[]
监听 channel
,当接收到新的消息时 listener
会以 listener(event, args...)
的形式被调用。
EN
ipcMain.once(channel, listener)
-
channel
String -
listener
Function
event
IpcMainEvent...args
any[]
Adds a one time listener
function for the event. This listener
is invoked only the next time a message is sent to channel
, after which it is removed.
EN
ipcMain.removeListener(channel, listener)
-
channel
String -
listener
Function
...args
any[]
从监听器数组中移除监听 channel
的指定 listener
。
EN
ipcMain.removeAllListeners([channel])
channel
String (optional)
删除所有监听者,或特指的 channel 的所有监听者.
EN
ipcMain.handle(channel, listener)
channel
Stringlistener
Function<Promise | any>event
IpcMainInvokeEvent...args
any[]
Adds a handler for an invoke
able IPC. This handler will be called whenever a renderer calls ipcRenderer.invoke(channel, ...args)
.
If listener
returns a Promise, the eventual result of the promise will be returned as a reply to the remote caller. Otherwise, the return value of the listener will be used as the value of the reply.
// Main process
ipcMain.handle('my-invokable-ipc', async (event, ...args) => {
const result = await somePromise(...args)
return result
})
// Renderer process
async () => {
const result = await ipcRenderer.invoke('my-invokable-ipc', arg1, arg2)
// ...
}
复制
The event
that is passed as the first argument to the handler is the same as that passed to a regular event listener. It includes information about which WebContents is the source of the invoke request.
EN
ipcMain.handleOnce(channel, listener)
channel
Stringlistener
Function<Promise | any>event
IpcMainInvokeEvent...args
any[]
Handles a single invoke
able IPC message, then removes the listener. See ipcMain.handle(channel, listener)
.
EN
ipcMain.removeHandler(channel)
channel
String
Removes any handler for channel
, if present.
EN
IpcMainEvent object
The documentation for the event
object passed to the callback
can be found in the ipc-main-event
structure docs.
EN
IpcMainInvokeEvent object
The documentation for the event
object passed to handle
callbacks can be found in the ipc-main-invoke-event
structure docs.
ipcRenderer
从渲染器进程到主进程的异步通信。
进程: Renderer
ipcRenderer
是一个 EventEmitter 的实例。 你可以使用它提供的一些方法从渲染进程 (web 页面) 发送同步或异步的消息到主进程。 也可以接收主进程回复的消息。
请从 ipcMain 查看代码示例。
EN
方法
ipcRenderer
模块使用以下方法来监听事件和发送消息。
EN
ipcRenderer.on(channel, listener)
-
channel
String -
listener
Function
event
IpcRendererEvent...args
any[]
监听 channel
,当接收到新的消息时 listener
会以 listener(event, args...)
的形式被调用。
EN
ipcRenderer.once(channel, listener)
-
channel
String -
listener
Function
event
IpcRendererEvent...args
any[]
Adds a one time listener
function for the event. This listener
is invoked only the next time a message is sent to channel
, after which it is removed.
EN
ipcRenderer.removeListener(channel, listener)
-
channel
String -
listener
Function
...args
any[]
从监听器数组中移除监听 channel
的指定 listener
。
EN
ipcRenderer.removeAllListeners(channel)
channel
String
移除所有的监听器,当指定 channel
时只移除与其相关的所有监听器。
EN
ipcRenderer.send(channel, ...args)
channel
String...args
any[]
通过channel
向渲染器进程发送异步消息,可以发送任意参数。 Arguments will be serialized with the Structured Clone Algorithm, just like [window.postMessage
][], so prototype chains will not be included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will throw an exception.
NOTE: Sending non-standard JavaScript types such as DOM objects or special Electron objects is deprecated, and will begin throwing an exception starting with Electron 9.
The main process handles it by listening for channel
with the ipcMain
module.
If you need to transfer a [MessagePort
][] to the main process, use ipcRenderer.postMessage
.
If you want to receive a single response from the main process, like the result of a method call, consider using ipcRenderer.invoke
.
EN
ipcRenderer.invoke(channel, ...args)
channel
String...args
any[]
Returns Promise<any>
- Resolves with the response from the main process.
Send a message to the main process via channel
and expect a result asynchronously. Arguments will be serialized with the Structured Clone Algorithm, just like [window.postMessage
][], so prototype chains will not be included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will throw an exception.
NOTE: Sending non-standard JavaScript types such as DOM objects or special Electron objects is deprecated, and will begin throwing an exception starting with Electron 9.
The main process should listen for channel
with ipcMain.handle()
.
例如:
// Renderer process
ipcRenderer.invoke('some-name', someArgument).then((result) => {
// ...
})
// Main process
ipcMain.handle('some-name', async (event, someArgument) => {
const result = await doSomeWork(someArgument)
return result
})
复制
If you need to transfer a [MessagePort
][] to the main process, use ipcRenderer.postMessage
.
If you do not need a response to the message, consider using ipcRenderer.send
.
EN
ipcRenderer.sendSync(channel, ...args)
channel
String...args
any[]
返回 any
- 由 ipcMain
处理程序发送过来的值。
Send a message to the main process via channel
and expect a result synchronously. Arguments will be serialized with the Structured Clone Algorithm, just like [window.postMessage
][], so prototype chains will not be included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will throw an exception.
NOTE: Sending non-standard JavaScript types such as DOM objects or special Electron objects is deprecated, and will begin throwing an exception starting with Electron 9.
主进程可以使用 ipcMain
监听 channel来接收这些消息,并通过 event.returnValue
设置回复消息。
⚠️ WARNING: Sending a synchronous message will block the whole renderer process until the reply is received, so use this method only as a last resort. It's much better to use the asynchronous version,
invoke()
.
EN
ipcRenderer.postMessage(channel, message, [transfer])
channel
Stringmessage
anytransfer
MessagePort[] (optional)
Send a message to the main process, optionally transferring ownership of zero or more [MessagePort
][] objects.
The transferred MessagePort
objects will be available in the main process as MessagePortMain
objects by accessing the ports
property of the emitted event.
例如:
// Renderer process
const { port1, port2 } = new MessageChannel()
ipcRenderer.postMessage('port', { message: 'hello' }, [port1])
// Main process
ipcMain.on('port', (e, msg) => {
const [port] = e.ports
// ...
})
复制
For more information on using MessagePort
and MessageChannel
, see the MDN documentation.
EN
ipcRenderer.sendTo(webContentsId, channel, ...args)
webContentsId
Numberchannel
String...args
any[]
Sends a message to a window with webContentsId
via channel
.
EN
ipcRenderer.sendToHost(channel, ...args)
channel
String...args
any[]
就像 ipcRenderer.send
,不同的是消息会被发送到 host 页面上的 <webview>
元素,而不是主进程。
EN
事件对象
The documentation for the event
object passed to the callback
can be found in the ipc-renderer-event
structure docs.
案例
主进程渲染进程通信
主进程
//为了管理应用程序的生命周期事件以及创建和控制浏览器窗口,您从 electron 包导入了 app 和 BrowserWindow 模块 。
const { app, BrowserWindow,ipcMain } = require('electron')
//在此之后,你定义了一个创建 新的浏览窗口的函数并将 nodeIntegration 设置为 true,将 index.html 文件加载到窗口中(第 12 行,稍后我们将讨论该文件)
function createWindow () {
const win = new BrowserWindow({
800,
height: 600,
webPreferences: {
//是否注入nodeapi
nodeIntegration: true,
//渲染进程是否启用remote模块
enableRemoteModule: true
}
})
win.loadFile('index.html')
}
//你通过调用 createWindow方法,在 electron app 第一次被初始化时创建了一个新的窗口。
app.whenReady().then(createWindow)
//您添加了一个新的侦听器,当应用程序不再有任何打开窗口时试图退出。 由于操作系统的 窗口管理行为 ,此监听器在 macOS 上是禁止操作的
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
//您添加一个新的侦听器,只有当应用程序激活后没有可见窗口时,才能创建新的浏览器窗口。 例如,在首次启动应用程序后或重启运行中的应用程序
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
//监听
ipcMain.on('send-message-to-main-test', (event, arg) => {
console.log('主线程接收到的消息:',arg)
//返回响应的事件
event.reply('send-message-to-render-test','来自主进程的问候')
})
渲染进程
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>进程通信</title>
</head>
<body>
<h1>进程通信</h1>
<button onclick="sendMessageMain()">发送信息给主进程</button>
</body>
<script>
const { ipcRenderer } = require('electron');
function sendMessageMain(){
//发送
ipcRenderer.send('send-message-to-main-test', '这是来自渲染进程的数据66666')
}
//监听
ipcRenderer.on('send-message-to-render-test', (event, arg) => {
console.log('渲染进程收到的消息:',arg)
})
</script>
</html>
主进程主动给渲染进程发消息
主进程
//为了管理应用程序的生命周期事件以及创建和控制浏览器窗口,您从 electron 包导入了 app 和 BrowserWindow 模块 。
const { app, BrowserWindow,ipcMain } = require('electron')
//在此之后,你定义了一个创建 新的浏览窗口的函数并将 nodeIntegration 设置为 true,将 index.html 文件加载到窗口中(第 12 行,稍后我们将讨论该文件)
function createWindow () {
const win = new BrowserWindow({
800,
height: 600,
webPreferences: {
//是否注入nodeapi
nodeIntegration: true,
//渲染进程是否启用remote模块
enableRemoteModule: true
}
})
win.loadFile('index.html')
//5s后 , 主动发送
setTimeout(()=>{
win.webContents.send('send-message-to-render-test', '这是主进程的主动搭讪')
}, 5000)
}
//你通过调用 createWindow方法,在 electron app 第一次被初始化时创建了一个新的窗口。
app.whenReady().then(createWindow)
//您添加了一个新的侦听器,当应用程序不再有任何打开窗口时试图退出。 由于操作系统的 窗口管理行为 ,此监听器在 macOS 上是禁止操作的
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
//您添加一个新的侦听器,只有当应用程序激活后没有可见窗口时,才能创建新的浏览器窗口。 例如,在首次启动应用程序后或重启运行中的应用程序
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
渲染进程
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>进程通信</title>
</head>
<body>
<h1>进程通信</h1>
<button onclick="sendMessageMain()">发送信息给主进程</button>
</body>
<script>
const { ipcRenderer } = require('electron');
//监听
ipcRenderer.on('send-message-to-render-test', (event, arg) => {
console.log('渲染进程收到的消息:',arg)
})
</script>
</html>