Skip to content

Commit

Permalink
docs: add IPC doc (#32059)
Browse files Browse the repository at this point in the history
* docs: add IPC doc

* fix: use "string" primitive

* use 'string' ipcrenderer

* use "number" primitive

* Update docs/tutorial/ipc.md

Co-authored-by: Jeremy Rose <nornagon@nornagon.net>

* Update docs/tutorial/ipc.md

Co-authored-by: Jeremy Rose <nornagon@nornagon.net>

* add code sample

Co-authored-by: Jeremy Rose <nornagon@nornagon.net>
  • Loading branch information
erickzhao and nornagon committed Feb 9, 2022
1 parent 254dbd7 commit e9a43be
Show file tree
Hide file tree
Showing 22 changed files with 798 additions and 184 deletions.
66 changes: 24 additions & 42 deletions docs/api/ipc-main.md
@@ -1,3 +1,10 @@
---
title: "ipcMain"
description: "Communicate asynchronously from the main process to renderer processes."
slug: ipc-main
hide_title: false
---

# ipcMain

> Communicate asynchronously from the main process to renderer processes.
Expand All @@ -9,7 +16,9 @@ process, it handles asynchronous and synchronous messages sent from a renderer
process (web page). Messages sent from a renderer will be emitted to this
module.

## Sending Messages
For usage examples, check out the [IPC tutorial].

## Sending messages

It is also possible to send messages from the main process to the renderer
process, see [webContents.send][web-contents-send] for more information.
Expand All @@ -21,36 +30,6 @@ process, see [webContents.send][web-contents-send] for more information.
coming from frames that aren't the main frame (e.g. iframes) whereas
`event.sender.send(...)` will always send to the main frame.

An example of sending and handling messages between the render and main
processes:

```javascript
// In main process.
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'
})
```

```javascript
// In renderer process (web page).
// NB. Electron APIs are only accessible from preload, unless contextIsolation is disabled.
// See https://www.electronjs.org/docs/tutorial/process-model#preload-scripts for more details.
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')
```

## Methods

The `ipcMain` module has the following method to listen for events:
Expand All @@ -59,7 +38,7 @@ The `ipcMain` module has the following method to listen for events:

* `channel` string
* `listener` Function
* `event` IpcMainEvent
* `event` [IpcMainEvent][ipc-main-event]
* `...args` any[]

Listens to `channel`, when a new message arrives `listener` would be called with
Expand All @@ -69,7 +48,7 @@ Listens to `channel`, when a new message arrives `listener` would be called with

* `channel` string
* `listener` Function
* `event` IpcMainEvent
* `event` [IpcMainEvent][ipc-main-event]
* `...args` any[]

Adds a one time `listener` function for the event. This `listener` is invoked
Expand All @@ -93,8 +72,8 @@ Removes listeners of the specified `channel`.
### `ipcMain.handle(channel, listener)`

* `channel` string
* `listener` Function<Promise\<void> | any>
* `event` IpcMainInvokeEvent
* `listener` Function<Promise\<void&#62; | any&#62;
* `event` [IpcMainInvokeEvent][ipc-main-invoke-event]
* `...args` any[]

Adds a handler for an `invoke`able IPC. This handler will be called whenever a
Expand All @@ -104,14 +83,14 @@ 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.

```js
// Main process
```js title='Main Process'
ipcMain.handle('my-invokable-ipc', async (event, ...args) => {
const result = await somePromise(...args)
return result
})
```

// Renderer process
```js title='Renderer Process'
async () => {
const result = await ipcRenderer.invoke('my-invokable-ipc', arg1, arg2)
// ...
Expand All @@ -130,7 +109,7 @@ provided to the renderer process. Please refer to
### `ipcMain.handleOnce(channel, listener)`

* `channel` string
* `listener` Function<Promise\<void> | any>
* `listener` Function<Promise\<void&#62; | any&#62;
* `event` IpcMainInvokeEvent
* `...args` any[]

Expand All @@ -146,13 +125,16 @@ Removes any handler for `channel`, if present.
## IpcMainEvent object

The documentation for the `event` object passed to the `callback` can be found
in the [`ipc-main-event`](structures/ipc-main-event.md) structure docs.
in the [`ipc-main-event`][ipc-main-event] structure docs.

## IpcMainInvokeEvent object

The documentation for the `event` object passed to `handle` callbacks can be
found in the [`ipc-main-invoke-event`](structures/ipc-main-invoke-event.md)
found in the [`ipc-main-invoke-event`][ipc-main-invoke-event]
structure docs.

[IPC tutorial]: ../tutorial/ipc.md
[event-emitter]: https://nodejs.org/api/events.html#events_class_eventemitter
[web-contents-send]: web-contents.md#contentssendchannel-args
[web-contents-send]: ../api/web-contents.md#contentssendchannel-args
[ipc-main-event]:../api/structures/ipc-main-event.md
[ipc-main-invoke-event]:../api/structures/ipc-main-invoke-event.md
25 changes: 16 additions & 9 deletions docs/api/ipc-renderer.md
@@ -1,3 +1,10 @@
---
title: "ipcRenderer"
description: "Communicate asynchronously from a renderer process to the main process."
slug: ipc-renderer
hide_title: false
---

# ipcRenderer

> Communicate asynchronously from a renderer process to the main process.
Expand All @@ -9,7 +16,7 @@ methods so you can send synchronous and asynchronous messages from the render
process (web page) to the main process. You can also receive replies from the
main process.

See [ipcMain](ipc-main.md) for code examples.
See [IPC tutorial](../tutorial/ipc.md) for code examples.

## Methods

Expand Down Expand Up @@ -70,7 +77,7 @@ throw an exception.
> them. Attempting to send such objects over IPC will result in an error.
The main process handles it by listening for `channel` with the
[`ipcMain`](ipc-main.md) module.
[`ipcMain`](./ipc-main.md) module.

If you need to transfer a [`MessagePort`][] to the main process, use [`ipcRenderer.postMessage`](#ipcrendererpostmessagechannel-message-transfer).

Expand Down Expand Up @@ -98,7 +105,7 @@ throw an exception.
> them. Attempting to send such objects over IPC will result in an error.
The main process should listen for `channel` with
[`ipcMain.handle()`](ipc-main.md#ipcmainhandlechannel-listener).
[`ipcMain.handle()`](./ipc-main.md#ipcmainhandlechannel-listener).

For example:

Expand All @@ -124,11 +131,11 @@ If you do not need a response to the message, consider using [`ipcRenderer.send`
* `channel` string
* `...args` any[]

Returns `any` - The value sent back by the [`ipcMain`](ipc-main.md) handler.
Returns `any` - The value sent back by the [`ipcMain`](./ipc-main.md) handler.

Send a message to the main process via `channel` and expect a result
synchronously. Arguments will be serialized with the [Structured Clone
Algorithm][SCA], just like [`window.postMessage`][], so prototype chains will not be
Algorithm][SCA], just like [`window.postMessage`], so prototype chains will not be
included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will
throw an exception.

Expand All @@ -140,13 +147,13 @@ throw an exception.
> Electron's IPC to the main process, as the main process would have no way to decode
> them. Attempting to send such objects over IPC will result in an error.
The main process handles it by listening for `channel` with [`ipcMain`](ipc-main.md) module,
The main process handles it by listening for `channel` with [`ipcMain`](./ipc-main.md) module,
and replies by setting `event.returnValue`.

> :warning: **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()`](ipc-renderer.md#ipcrendererinvokechannel-args).
> [`invoke()`](./ipc-renderer.md#ipcrendererinvokechannel-args).
### `ipcRenderer.postMessage(channel, message, [transfer])`

Expand All @@ -158,7 +165,7 @@ 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`](message-port-main.md) objects by accessing the `ports`
[`MessagePortMain`](./message-port-main.md) objects by accessing the `ports`
property of the emitted event.

For example:
Expand Down Expand Up @@ -197,7 +204,7 @@ the host page instead of the main process.
## Event object

The documentation for the `event` object passed to the `callback` can be found
in the [`ipc-renderer-event`](structures/ipc-renderer-event.md) structure docs.
in the [`ipc-renderer-event`](./structures/ipc-renderer-event.md) structure docs.

[event-emitter]: https://nodejs.org/api/events.html#events_class_eventemitter
[SCA]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm
Expand Down
Empty file.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

14 changes: 14 additions & 0 deletions docs/fiddles/ipc/pattern-1/index.html
@@ -0,0 +1,14 @@
<!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>

0 comments on commit e9a43be

Please sign in to comment.