2013-09-09 07:35:57 +00:00
# remote
2013-08-14 22:43:35 +00:00
2013-12-30 14:06:33 +00:00
The `remote` module provides a simple way to do inter-process communication
2015-03-26 15:20:31 +00:00
between the renderer process and the main process.
2014-05-10 03:51:25 +00:00
2015-05-22 02:32:59 +00:00
In Electron, only GUI-unrelated modules are available in the renderer process.
2015-03-26 15:20:31 +00:00
Without the `remote` module, users who wanted to call a main process API in
2014-05-10 03:51:25 +00:00
the renderer process would have to explicitly send inter-process messages
2015-03-26 15:20:31 +00:00
to the main process. With the `remote` module, users can invoke methods of
main process object without explicitly sending inter-process messages,
2014-05-10 03:51:25 +00:00
similar to Java's
2013-12-30 14:06:33 +00:00
[RMI ](http://en.wikipedia.org/wiki/Java_remote_method_invocation ).
An example of creating a browser window in renderer process:
2013-08-14 22:43:35 +00:00
```javascript
var remote = require('remote');
var BrowserWindow = remote.require('browser-window');
var win = new BrowserWindow({ width: 800, height: 600 });
win.loadUrl('https://github.com');
```
2015-06-06 11:38:00 +00:00
Note: for the reverse (access renderer process from main process), you can use [webContents.executeJavascript ](https://github.com/atom/electron/blob/master/docs/api/browser-window.md#browserwindowwebcontents ).
2013-12-30 14:06:33 +00:00
## Remote objects
2014-05-10 03:51:25 +00:00
Each object (including functions) returned by the `remote` module represents an
2015-03-26 15:20:31 +00:00
object in the main process (we call it a remote object or remote function).
2014-05-10 03:51:25 +00:00
When you invoke methods of a remote object, call a remote function, or create
2013-12-30 14:06:33 +00:00
a new object with the remote constructor (function), you are actually sending
synchronous inter-process messages.
2014-05-10 03:51:25 +00:00
In the example above, both `BrowserWindow` and `win` were remote objects and
`new BrowserWindow` didn't create a `BrowserWindow` object in the renderer process.
2015-03-26 15:20:31 +00:00
Instead, it created a `BrowserWindow` object in the main process and returned the
2014-05-10 03:51:25 +00:00
corresponding remote object in the renderer process, namely the `win` object.
2013-12-30 14:06:33 +00:00
2013-08-14 22:43:35 +00:00
## Lifetime of remote objects
2015-04-16 03:31:12 +00:00
Electron makes sure that as long as the remote object in the renderer process
2013-12-30 14:06:33 +00:00
lives (in other words, has not been garbage collected), the corresponding object
2015-03-26 15:20:31 +00:00
in the main process would never be released. When the remote object has been
garbage collected, the corresponding object in the main process would be
2013-12-30 14:06:33 +00:00
dereferenced.
2013-08-14 22:43:35 +00:00
2014-05-10 03:51:25 +00:00
If the remote object is leaked in renderer process (e.g. stored in a map but never
2015-03-26 15:20:31 +00:00
freed), the corresponding object in the main process would also be leaked,
2014-05-10 03:51:25 +00:00
so you should be very careful not to leak remote objects.
2013-08-14 22:43:35 +00:00
2013-12-30 14:06:33 +00:00
Primary value types like strings and numbers, however, are sent by copy.
2013-08-14 22:43:35 +00:00
2015-03-26 15:20:31 +00:00
## Passing callbacks to the main process
2013-08-14 22:43:35 +00:00
2015-05-10 05:54:37 +00:00
Some APIs in the main process accept callbacks, and it would be tempting to
2014-05-10 03:51:25 +00:00
pass callbacks when calling a remote function. The `remote` module does support
doing this, but you should also be extremely careful with this.
2013-08-14 22:43:35 +00:00
2015-03-26 15:20:31 +00:00
First, in order to avoid deadlocks, the callbacks passed to the main process
are called asynchronously, so you should not expect the main process to
2013-12-30 14:06:33 +00:00
get the return value of the passed callbacks.
2015-03-26 15:20:31 +00:00
Second, the callbacks passed to the main process will not get released
2014-05-10 03:51:25 +00:00
automatically after they are called. Instead, they will persistent until the
2015-03-26 15:20:31 +00:00
main process garbage-collects them.
2013-12-30 14:06:33 +00:00
2014-05-10 03:51:25 +00:00
For example, the following code seems innocent at first glance. It installs a
2013-12-30 14:06:33 +00:00
callback for the `close` event on a remote object:
2013-08-14 22:43:35 +00:00
```javascript
var remote = require('remote');
remote.getCurrentWindow().on('close', function() {
// blabla...
});
```
2015-03-26 15:20:31 +00:00
The problem is that the callback would be stored in the main process until you
2013-12-30 14:06:33 +00:00
explicitly uninstall it! So each time you reload your window, the callback would
2014-05-10 03:51:25 +00:00
be installed again and previous callbacks would just leak. To make things
2013-12-30 14:06:33 +00:00
worse, since the context of previously installed callbacks have been released,
2015-03-26 15:20:31 +00:00
when the `close` event was emitted, exceptions would be raised in the main process.
2013-08-14 22:43:35 +00:00
2014-05-10 03:51:25 +00:00
Generally, unless you are clear what you are doing, you should always avoid
2015-03-26 15:20:31 +00:00
passing callbacks to the main process.
2013-08-14 22:43:35 +00:00
2013-12-30 15:08:42 +00:00
## Remote buffer
2014-05-10 03:51:25 +00:00
An instance of node's `Buffer` is an object, so when you get a `Buffer` from
2015-03-26 15:20:31 +00:00
the main process, what you get is indeed a remote object (let's call it remote
2013-12-30 15:08:42 +00:00
buffer), and everything would just follow the rules of remote objects.
2014-05-10 03:51:25 +00:00
However you should remember that although a remote buffer behaves like the real
2013-12-30 15:08:42 +00:00
`Buffer` , it's not a `Buffer` at all. If you pass a remote buffer to node APIs
2014-05-10 03:51:25 +00:00
that accept a `Buffer` , you should assume the remote buffer would be treated
2013-12-30 15:08:42 +00:00
like a normal object, instead of a `Buffer` .
2014-05-10 03:51:25 +00:00
For example, you can call `BrowserWindow.capturePage` in the renderer process, which
returns a `Buffer` by calling the passed callback:
2013-12-30 15:08:42 +00:00
```javascript
var remote = require('remote');
var fs = require('fs');
2015-06-06 11:20:47 +00:00
remote.getCurrentWindow().capturePage(function(image) {
2015-06-06 11:31:22 +00:00
var buf = image.toPng();
2013-12-30 15:08:42 +00:00
fs.writeFile('/tmp/screenshot.png', buf, function(err) {
console.log(err);
});
});
```
But you may be surprised to find that the file written was corrupted. This is
2014-05-10 03:51:25 +00:00
because when you called `fs.writeFile` , thinking that `buf` was a `Buffer` when
in fact it was a remote buffer, and it was converted to string before it was
written to the file. Since `buf` contained binary data and could not be represented
by a UTF-8 encoded string, the written file was corrupted.
2013-12-30 15:08:42 +00:00
2015-03-26 15:20:31 +00:00
The work-around is to write the `buf` in the main process, where it is a real
2013-12-30 15:08:42 +00:00
`Buffer` :
```javascript
var remote = require('remote');
2015-06-06 11:20:47 +00:00
remote.getCurrentWindow().capturePage(function(image) {
2015-06-06 11:31:22 +00:00
var buf = image.toPng();
2013-12-30 15:08:42 +00:00
remote.require('fs').writeFile('/tmp/screenshot.png', buf, function(err) {
console.log(err);
});
});
```
The same thing could happen for all native types, but usually it would just
throw a type error. The `Buffer` deserves your special attention because it
2014-05-10 03:51:25 +00:00
might be converted to string, and APIs accepting `Buffer` usually accept string
too, and data corruption could happen when it contains binary data.
2013-12-30 15:08:42 +00:00
2013-08-14 22:43:35 +00:00
## remote.require(module)
* `module` String
2015-03-26 15:20:31 +00:00
Returns the object returned by `require(module)` in the main process.
2013-08-14 22:43:35 +00:00
## remote.getCurrentWindow()
2015-01-21 21:47:28 +00:00
Returns the [BrowserWindow ](browser-window.md ) object which this web page
belongs to.
2013-08-14 22:43:35 +00:00
2015-05-11 06:05:20 +00:00
## remote.getCurrentWebContent()
Returns the WebContents object of this web page.
2013-08-14 22:43:35 +00:00
## remote.getGlobal(name)
* `name` String
2015-03-26 15:20:31 +00:00
Returns the global variable of `name` (e.g. `global[name]` ) in the main
2013-12-30 14:06:33 +00:00
process.
2013-08-14 22:43:35 +00:00
## remote.process
2015-03-26 15:20:31 +00:00
Returns the `process` object in the main process. This is the same as
2014-05-10 03:51:25 +00:00
`remote.getGlobal('process')` , but gets cached.