簡介
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({
width: 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({
width: 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>