Valence
view release on metacpan or search on metacpan
prettified dump of the JSON protocol between the perl and electron
process
Sending to electron >>>>>>>>>>>>>>>>>
{
"args" : [
"app"
],
"cmd" : "call",
"method" : "require",
"save" : "1"
}
Sending to electron >>>>>>>>>>>>>>>>>
{
"args" : [
"ready",
null
],
"args_cb" : [
[
1,
1
]
],
"cmd" : "call",
"method" : "on",
"obj" : "1",
"save" : "3"
}
...
<<<<<<<<<<<<<<<<< Message from electron
{
"args" : [
{}
],
"cb" : 1,
"cmd" : "cb"
}
If you set "VALENCE_DEBUG" to 2 or higher, you will also see the
standard error output from the electron process, which includes
"console.error()" output.
IPC
An essential feature of valence is providing bi-directional,
asynchronous messaging between your application and the browser render
process. It does this over the standard input/standard output interface
provided by "valence.js". Without this support we would need to allocate
some kind of network port or unix socket and start something like an
AJAX or websocket server.
BROWSER TO PERL
In order for the browser to send a message to your perl code, it should
execute something like the following javascript code:
var ipcRenderer = require('electron').ipcRenderer;
ipcRenderer.send('my-event', 'my message');
On the perl side, you receive these messages like so:
my $ipcMain = $electron->attr('ipcMain');
$ipcMain->on('my-event' => sub {
my ($event, $message) = @_;
print $message; ## prints 'my message'
});
PERL TO BROWSER
Sending messages from perl to the browser should use code like this:
my $web_contents = $main_window->attr('webContents');
$web_contents->send('my-event' => 'my message');
And the javascript side can receive these messages like so:
var ipcRenderer = require('electron').ipcRenderer;
ipcRenderer.on('my-event', function(event, message) {
console.log(message); // prints 'my message'
});
IPC READY EVENTS
Before applications can send messages from perl to javascript, the
"ipcRenderer.on()" function must have been called to handle these
messages. If you try to send a message before this, it is likely that
the message will be delivered to the browser before the handler has been
installed so your message will be lost. Applications should have
javascript send a message indicating that the communication channel is
ready, after which the perl component can begin sending messages to the
browser.
For an example of how this is done, see the "t/ipc.t" test and how the
perl side subscribes to a "ready" IPC message before attempting to send
its "ping" message, and how the "t/static/remote.html" arranges for
javascript to send the "ready" message after it has installed its "ping"
handler.
TESTS
Currently this software has two tests, "load.t" which verifies Valence
is installed and "ipc.t" which starts electron and then proceeds to
confirm bi-directional transfer of messages between javascript and perl.
BACKWARDS COMPATIBILITY
The extent to which this module is backwards-compatible depends on the
underlying "electron" project. The API was changed drastically between
electron 0.25.1 and 1.0.1 (corresponding to Valence releases 0.100 and
0.200) so you will have to port your apps over. Sorry about that. The
changes are described in more detail in this electron blog post
<http://electron.atom.io/blog/2015/11/17/electron-api-changes>.
Presumably now that "electron" has reached version 1.0.0 it should now
be more stable.
BUGS
A fairly large limitation with the proxying approach is that event
handlers cannot prevent the default event from firing (ie with
"event.preventDefault()"). This is because the stub event handler in
javascript simply forwards the event trigger and its arguments to the
perl process and returns.
As mentioned above, "sub"s nested inside hashes or arrays will currently
not properly get stubbed out (but this can be fixed if needed).
Attributes should ideally be accessed via a hash reference overload
instead of the "attr" special method.
"new" methods cannot yet accept more than one parameter (due to a
limitation in "valence.js" -- how do you do this in JS?).
When a callback function is deleted on the javascript side, the
perl-side doesn't know about this so its corresponding callback will
remain forever. Is there a way to detect this in JS?
It currently always sends a "save" (immediately followed by a "destroy")
even when it doesn't need the value. This is inefficient and should be
fixed using "wantarray".
( run in 1.770 second using v1.01-cache-2.11-cpan-39bf76dae61 )