From db780e55a2d725b2a322cce06a63563789897909 Mon Sep 17 00:00:00 2001 From: gwleuverink Date: Thu, 31 Oct 2024 17:15:22 +0100 Subject: [PATCH 1/9] add php & artisan processes --- .../docs/1/digging-deeper/child-process.md | 67 +++++++++++++++---- 1 file changed, 53 insertions(+), 14 deletions(-) diff --git a/resources/views/docs/1/digging-deeper/child-process.md b/resources/views/docs/1/digging-deeper/child-process.md index 1c47e21a..cb9d1eb4 100644 --- a/resources/views/docs/1/digging-deeper/child-process.md +++ b/resources/views/docs/1/digging-deeper/child-process.md @@ -7,7 +7,7 @@ order: 700 Child Processes allow your application to spin up managed processes, forked from your app's main process. This is great for long-running processes that you want to interact with repeatedly during the life of your application. - + Child Processes can be managed from your application using a straightforward API. When your app quits, these processes get shut down gracefully. @@ -26,10 +26,12 @@ application. --- ## Alternatives + Before deciding to use a Child Process, consider the alternatives available to you. You should pick the most appropriate for the problem you're trying to solve: ### Queues + The [queue runner](queues) is useful for very simply offloading _Laravel_ tasks to the background. Each task must be a Laravel queued [Job](https://laravel.com/docs/queues#creating-jobs). @@ -37,6 +39,7 @@ Any queued jobs that don't get processed before your app is quit, will get proce queue runner) starts again. ### Scheduler + The Laravel scheduler runs as normal (every minute) inside a NativePHP application. You can add [scheduled tasks](https://laravel.com/docs/scheduling) to your application just as you normally would, to have them run on a regular schedule. @@ -47,16 +50,18 @@ Any scheduled tasks that would have run while your application isn't running wil only be able to run while your application is running.** ### `shell_exec`, `proc_open` etc + PHP has good built-in support for running arbitrary programs in separate processes. For example: -- [`shell_exec`](https://www.php.net/manual/en/function.shell-exec.php) allows you to run commands and return their -output to your application. -- [`proc_open`](https://www.php.net/manual/en/function.proc-open.php) allows you to spin up a command with more control -over how its input and output streams are handled. +- [`shell_exec`](https://www.php.net/manual/en/function.shell-exec.php) allows you to run commands and return their + output to your application. +- [`proc_open`](https://www.php.net/manual/en/function.proc-open.php) allows you to spin up a command with more control + over how its input and output streams are handled. While these can be used in your NativePHP application, consider that they: -- May block the script that is executing them until the sub-process has finished. -- May become orphaned from your application, allowing them to continue running after your app has quit. + +- May block the script that is executing them until the sub-process has finished. +- May become orphaned from your application, allowing them to continue running after your app has quit. Runaway orphaned processes could negatively impact your user's system and can become tricky to manage without user intervention. You should be cautious about starting processes this way. @@ -64,6 +69,7 @@ intervention. You should be cautious about starting processes this way. --- ## Starting a Child Process + Each Child Process must have a unique alias. This is the name you will use to reference and interact with this process throughout your application. @@ -89,6 +95,7 @@ may fail for a number of reasons. [`ProcessSpawned` event](#codeprocessspawnedcode).** ### Current Working Directory + By default, the child process will use the working directory of your application as it's "current working directory" (`cwd`). However, you can explicitly change this if needed by passing a string path to the `$cwd` parameter of the `start` method: @@ -102,6 +109,7 @@ ChildProcess::start( ``` ### Persistent Processes + You may mark a process as `persistent` to indicate that the runtime should make sure that once it has been started it is always running. This works similarly to tools like [`supervisord`](http://supervisord.org/), ensuring that the process gets booted up again in case it crashes. @@ -116,9 +124,26 @@ ChildProcess::start( **The only way to stop a persistent process is for your application to quit.** +### PHP scripts + +For your convenience NativePHP provides a simple method to execute PHP scripts with in the background using NativePHP's packaged PHP binary: + +```php +ChildProcess::php('path/to/script.php', alias: 'script'); +``` + +### Artisan commands + +NativePHP provides a similar method to run artisan commands: + +```php +ChildProcess::artisan('smtp:serve', alias: 'smtp-server'); +``` + ## Getting running processes ### Getting a single process + You can use the `ChildProcess` facade's `get` method to get a running process with a given alias: ```php @@ -128,6 +153,7 @@ $tail = ChildProcess::get('tail'); This will return a `Native\Laravel\ChildProcess` instance. ### Getting all processes + You can use the `ChildProcess` facade's `all` method to get all running processes: ```php @@ -137,16 +163,18 @@ $tail = ChildProcess::all(); This will return an array of `Native\Laravel\ChildProcess` instances. ## Sending input + There are multiple ways to provide input to your Child Process: -- The environment. -- Arguments to the command. -- Its standard input stream (`STDIN`). -- A custom interface, e.g. a network socket. +- The environment. +- Arguments to the command. +- Its standard input stream (`STDIN`). +- A custom interface, e.g. a network socket. Which you use will depend on what the program is capable of handling. ### Environment + Child Processes will inherit the environment available to your application by default. If needed, you can provide extra environment variables when starting the process via the `$env` parameter of the `start` method: @@ -161,6 +189,7 @@ ChildProcess::start( ``` ### Command line arguments + You can pass arguments to the program via the `$cmd` parameter of the `start` method. This accepts a `string` or an `array`, whichever you prefer to use: @@ -172,6 +201,7 @@ ChildProcess::start( ``` ### Messaging a Child Process + You may send messages to a running child process's standard input stream (`STDIN`) using the `message` method: ```php @@ -187,13 +217,15 @@ ChildProcess::message('Hello, world!', 'tail'); The message format and how they are handled will be determined by the program you're running. ## Handling output + A Child Process may send output via any of the following interfaces: -- Its standard output stream (`STDOUT`). -- Its standard error stream (`STDERR`). -- A custom interface, e.g. a network socket. +- Its standard output stream (`STDOUT`). +- Its standard error stream (`STDERR`). +- A custom interface, e.g. a network socket. ### Listening for Output (`STDOUT`) + You may receive standard output for a process by registering an event listener for the [`MessageReceived`](#codemessagereceivedcode) event: @@ -209,6 +241,7 @@ Event::listen(MessageReceived::class, function (MessageReceived $event) { ``` ### Listening for Errors (`STDERR`) + You may receive standard errors for a process by registering an event listener for the [`ErrorReceived`](#codeerrorreceivedcode) event: @@ -224,6 +257,7 @@ Event::listen(ErrorReceived::class, function (ErrorReceived $event) { ``` ## Stopping a Child Process + Your child processes will shut down when your application exits. However, you may also choose to stop them manually or provide this control to your user. @@ -243,6 +277,7 @@ This will attempt to stop the process gracefully. The [`ProcessExited`](#codepro dispatched if the process exits. ## Restarting a Child Process + As a convenience, you may simply restart a Child Process using the `restart` method. This may be useful in cases where the program has become unresponsive and you simply need to "reboot" it. @@ -279,6 +314,7 @@ To learn more about NativePHP's broadcasting capabilities, please refer to the [Broadcasting](/docs/digging-deeper/broadcasting) section. ### `ProcessSpawned` + This `Native\Laravel\Events\ChildProcess\ProcessSpawned` event will be dispatched when a Child Process has successfully been spawned. The payload of the event contains the `$alias` and the `$pid` of the process. @@ -286,15 +322,18 @@ been spawned. The payload of the event contains the `$alias` and the `$pid` of t process.** ### `ProcessExited` + This `Native\Laravel\Events\ChildProcess\ProcessExited` event will be dispatched when a Child Process exits. The payload of the event contains the `$alias` of the process and its exit `$code`. ### `MessageReceived` + This `Native\Laravel\Events\ChildProcess\MessageReceived` event will be dispatched when the Child Process emits some output via its standard output stream (`STDOUT`). The payload of the event contains the `$alias` of the process and the message `$data`. ### `ErrorReceived` + This `Native\Laravel\Events\ChildProcess\ErrorReceived` event will be dispatched when the Child Process emits an error via its standard error stream (`STDERR`). The payload of the event contains the `$alias` of the process and the error `$data`. From 52c8ebdfbf0639f5e39b02c2f6a0c24a8ffb463b Mon Sep 17 00:00:00 2001 From: gwleuverink Date: Thu, 31 Oct 2024 20:39:00 +0100 Subject: [PATCH 2/9] add first code sample above the fold --- resources/views/docs/1/digging-deeper/child-process.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/resources/views/docs/1/digging-deeper/child-process.md b/resources/views/docs/1/digging-deeper/child-process.md index cb9d1eb4..8556f621 100644 --- a/resources/views/docs/1/digging-deeper/child-process.md +++ b/resources/views/docs/1/digging-deeper/child-process.md @@ -14,6 +14,15 @@ get shut down gracefully. "Spawning" a Child Process is like running a command from the CLI. Any command you can run in the terminal can be a Child Process. +```php +ChildProcess::start( + cmd: 'tail -f storage/logs/laravel.log', + alias: 'tail' +); +``` + +Any process invoked using the ChildProcess facade will be non-blocking and keep running in the background. Even if the request that triggered it has finished. + **Bear in mind that your Child Process ("command line") arguments may need to differ depending on which platform your application is running on (Mac/Linux vs Windows).** From 08e0cd0ebc1ada409364df7a989f359ad095e9fd Mon Sep 17 00:00:00 2001 From: gwleuverink Date: Thu, 31 Oct 2024 21:10:36 +0100 Subject: [PATCH 3/9] added front-end listener example --- resources/views/docs/1/digging-deeper/child-process.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/resources/views/docs/1/digging-deeper/child-process.md b/resources/views/docs/1/digging-deeper/child-process.md index 8556f621..3d3051f4 100644 --- a/resources/views/docs/1/digging-deeper/child-process.md +++ b/resources/views/docs/1/digging-deeper/child-process.md @@ -317,7 +317,15 @@ protected $listen = [ ``` Sometimes you may want to listen and react to these events in real-time, which is why NativePHP also broadcasts all -Child Process events to the `nativephp` broadcast channel. +Child Process events to the `nativephp` broadcast channel. Any events broadcasted this way also get dispatched over IPC, enabling you to react to them on the front-end without using websockets. + +```js +Native.on("Native\\Laravel\\Events\\ChildProcess\\MessageReceived", (event) => { + if (event.alias === "tail") { + container.append(event.data); + } +}); +``` To learn more about NativePHP's broadcasting capabilities, please refer to the [Broadcasting](/docs/digging-deeper/broadcasting) section. From 3dc6cdae26e95b48610f6dd80bbcd881d5485412 Mon Sep 17 00:00:00 2001 From: gwleuverink Date: Thu, 31 Oct 2024 23:57:23 +0100 Subject: [PATCH 4/9] replaced -n50 with -f --- resources/views/docs/1/digging-deeper/child-process.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/resources/views/docs/1/digging-deeper/child-process.md b/resources/views/docs/1/digging-deeper/child-process.md index 3d3051f4..e245cad7 100644 --- a/resources/views/docs/1/digging-deeper/child-process.md +++ b/resources/views/docs/1/digging-deeper/child-process.md @@ -88,7 +88,7 @@ You may start a process using the `ChildProcess` facade: use Native\Laravel\Facades\ChildProcess; ChildProcess::start( - cmd: 'tail -n50 storage/logs/laravel.log', + cmd: 'tail -f storage/logs/laravel.log', alias: 'tail' ); ``` @@ -111,7 +111,7 @@ By default, the child process will use the working directory of your application ```php ChildProcess::start( - cmd: ['tail', '-n50', 'logs/laravel.log'], + cmd: ['tail', '-f', 'logs/laravel.log'], alias: 'tail', cwd: storage_path() ); @@ -125,7 +125,7 @@ process gets booted up again in case it crashes. ```php ChildProcess::start( - cmd: ['tail', '-n50', 'logs/laravel.log'], + cmd: ['tail', '-f', 'logs/laravel.log'], alias: 'tail', persistent: true ); @@ -166,7 +166,7 @@ This will return a `Native\Laravel\ChildProcess` instance. You can use the `ChildProcess` facade's `all` method to get all running processes: ```php -$tail = ChildProcess::all(); +$processes = ChildProcess::all(); ``` This will return an array of `Native\Laravel\ChildProcess` instances. @@ -204,7 +204,7 @@ You can pass arguments to the program via the `$cmd` parameter of the `start` me ```php ChildProcess::start( - cmd: ['tail', '-n50', 'storage/logs/laravel.log'], + cmd: ['tail', '-f', 'storage/logs/laravel.log'], alias: 'tail' ); ``` From 72d1025a3b667bcd8fa5f6997e5a5a1f91c4f147 Mon Sep 17 00:00:00 2001 From: gwleuverink Date: Fri, 1 Nov 2024 00:04:24 +0100 Subject: [PATCH 5/9] remove recursion in code sample --- resources/views/docs/1/digging-deeper/child-process.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/views/docs/1/digging-deeper/child-process.md b/resources/views/docs/1/digging-deeper/child-process.md index e245cad7..026465ba 100644 --- a/resources/views/docs/1/digging-deeper/child-process.md +++ b/resources/views/docs/1/digging-deeper/child-process.md @@ -244,7 +244,7 @@ use Native\Laravel\Events\ChildProcess\MessageReceived; Event::listen(MessageReceived::class, function (MessageReceived $event) { if ($event->alias === 'tail') { - info($event->data); + // } }); ``` @@ -260,7 +260,7 @@ use Native\Laravel\Events\ChildProcess\ErrorReceived; Event::listen(ErrorReceived::class, function (ErrorReceived $event) { if ($event->alias === 'tail') { - info($event->data); + // } }); ``` From f1b9a94112cac3885d1b319a52bb148c57f29295 Mon Sep 17 00:00:00 2001 From: gwleuverink Date: Fri, 1 Nov 2024 00:44:03 +0100 Subject: [PATCH 6/9] restructure events --- .../docs/1/digging-deeper/child-process.md | 87 +++++++++---------- 1 file changed, 41 insertions(+), 46 deletions(-) diff --git a/resources/views/docs/1/digging-deeper/child-process.md b/resources/views/docs/1/digging-deeper/child-process.md index 026465ba..d83f2b41 100644 --- a/resources/views/docs/1/digging-deeper/child-process.md +++ b/resources/views/docs/1/digging-deeper/child-process.md @@ -225,46 +225,6 @@ ChildProcess::message('Hello, world!', 'tail'); The message format and how they are handled will be determined by the program you're running. -## Handling output - -A Child Process may send output via any of the following interfaces: - -- Its standard output stream (`STDOUT`). -- Its standard error stream (`STDERR`). -- A custom interface, e.g. a network socket. - -### Listening for Output (`STDOUT`) - -You may receive standard output for a process by registering an event listener for the -[`MessageReceived`](#codemessagereceivedcode) event: - -```php -use Illuminate\Support\Facades\Event; -use Native\Laravel\Events\ChildProcess\MessageReceived; - -Event::listen(MessageReceived::class, function (MessageReceived $event) { - if ($event->alias === 'tail') { - // - } -}); -``` - -### Listening for Errors (`STDERR`) - -You may receive standard errors for a process by registering an event listener for the -[`ErrorReceived`](#codeerrorreceivedcode) event: - -```php -use Illuminate\Support\Facades\Event; -use Native\Laravel\Events\ChildProcess\ErrorReceived; - -Event::listen(ErrorReceived::class, function (ErrorReceived $event) { - if ($event->alias === 'tail') { - // - } -}); -``` - ## Stopping a Child Process Your child processes will shut down when your application exits. However, you may also choose to stop them manually or @@ -302,18 +262,53 @@ Alternatively, you may use the `ChildProcess` facade to restart a process via it ChildProcess::restart('tail'); ``` +## Handling output + +A Child Process may send output via any of the following interfaces: + +- Its standard output stream (`STDOUT`). +- Its standard error stream (`STDERR`). +- A custom interface, e.g. a network socket. +- Broadcasting a Custom Event + +`STDOUT`, `STDERR` & [Custom Events](/docs/1/digging-deeper/broadcasting#custom-events) are dispatched using Laravel's event system. + +You may listen to these events by registering a listener in your app service provider, or on the front end using the [Native helper](/docs/1/digging-deeper/broadcasting#listening-with-javascript). + +Please see the [Events](#events) section for a full list of events. + +### Listening for Output (`STDOUT`) + +You may receive standard output for a process by registering an event listener for the +[`MessageReceived`](#codemessagereceivedcode) event: + +### Listening for Errors (`STDERR`) + +You may receive standard errors for a process by registering an event listener for the +[`ErrorReceived`](#codeerrorreceivedcode) event: + ## Events NativePHP provides a simple way to listen for Child Process events. -All events get dispatched as regular Laravel events, so you may use your `EventServiceProvider` to register listeners. +All events get dispatched as regular Laravel events, so you may use your `AppServiceProvider` to register listeners. ```php -protected $listen = [ - 'Native\Laravel\Events\ChildProcess\MessageReceived' => [ - 'App\Listeners\MainLoopEvent', - ], -]; +use Illuminate\Support\Facades\Event; +use Native\Laravel\Events\ChildProcess\MessageReceived; + +/** + * Bootstrap any application services. + */ +public function boot(): void +{ + Event::listen(MessageReceived::class, function(MessageReceived $event) { + if ($event->alias === 'tail') { + // + } + }); +} + ``` Sometimes you may want to listen and react to these events in real-time, which is why NativePHP also broadcasts all From f1f33fd124ff8c2a3b8d32726a494bbc60fe99e0 Mon Sep 17 00:00:00 2001 From: gwleuverink Date: Fri, 1 Nov 2024 01:01:09 +0100 Subject: [PATCH 7/9] add reference to persistent processes in 'quit' section --- resources/views/docs/1/digging-deeper/child-process.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/resources/views/docs/1/digging-deeper/child-process.md b/resources/views/docs/1/digging-deeper/child-process.md index d83f2b41..860d64c9 100644 --- a/resources/views/docs/1/digging-deeper/child-process.md +++ b/resources/views/docs/1/digging-deeper/child-process.md @@ -245,6 +245,8 @@ ChildProcess::stop('tail'); This will attempt to stop the process gracefully. The [`ProcessExited`](#codeprocessexitedcode) event will be dispatched if the process exits. +Note that [persistent processes](/docs/1/digging-deeper/child-process#persistent-processes) restart when you stop them manually. The only way to stop a persistent process is by quitting the application. + ## Restarting a Child Process As a convenience, you may simply restart a Child Process using the `restart` method. This may be useful in cases where From 7ac7febb2b14f5d66ef6f0e999e51dd9625e1c20 Mon Sep 17 00:00:00 2001 From: gwleuverink Date: Fri, 1 Nov 2024 10:21:16 +0100 Subject: [PATCH 8/9] moved input & output sections together --- .../docs/1/digging-deeper/child-process.md | 78 +++++++++---------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/resources/views/docs/1/digging-deeper/child-process.md b/resources/views/docs/1/digging-deeper/child-process.md index 860d64c9..1d14888a 100644 --- a/resources/views/docs/1/digging-deeper/child-process.md +++ b/resources/views/docs/1/digging-deeper/child-process.md @@ -171,6 +171,45 @@ $processes = ChildProcess::all(); This will return an array of `Native\Laravel\ChildProcess` instances. +## Stopping a Child Process + +Your child processes will shut down when your application exits. However, you may also choose to stop them manually or +provide this control to your user. + +If you have a `Native\Laravel\ChildProcess` instance, you may call the `stop` method on it: + +```php +$tail->stop(); +``` + +Alternatively, you may use the `ChildProcess` facade to stop a process via its alias: + +```php +ChildProcess::stop('tail'); +``` + +This will attempt to stop the process gracefully. The [`ProcessExited`](#codeprocessexitedcode) event will be +dispatched if the process exits. + +Note that [persistent processes](/docs/1/digging-deeper/child-process#persistent-processes) restart when you stop them manually. The only way to stop a persistent process is by quitting the application. + +## Restarting a Child Process + +As a convenience, you may simply restart a Child Process using the `restart` method. This may be useful in cases where +the program has become unresponsive and you simply need to "reboot" it. + +If you have a `Native\Laravel\ChildProcess` instance, you may call the `restart` method on it: + +```php +$tail->stop(); +``` + +Alternatively, you may use the `ChildProcess` facade to restart a process via its alias: + +```php +ChildProcess::restart('tail'); +``` + ## Sending input There are multiple ways to provide input to your Child Process: @@ -225,45 +264,6 @@ ChildProcess::message('Hello, world!', 'tail'); The message format and how they are handled will be determined by the program you're running. -## Stopping a Child Process - -Your child processes will shut down when your application exits. However, you may also choose to stop them manually or -provide this control to your user. - -If you have a `Native\Laravel\ChildProcess` instance, you may call the `stop` method on it: - -```php -$tail->stop(); -``` - -Alternatively, you may use the `ChildProcess` facade to stop a process via its alias: - -```php -ChildProcess::stop('tail'); -``` - -This will attempt to stop the process gracefully. The [`ProcessExited`](#codeprocessexitedcode) event will be -dispatched if the process exits. - -Note that [persistent processes](/docs/1/digging-deeper/child-process#persistent-processes) restart when you stop them manually. The only way to stop a persistent process is by quitting the application. - -## Restarting a Child Process - -As a convenience, you may simply restart a Child Process using the `restart` method. This may be useful in cases where -the program has become unresponsive and you simply need to "reboot" it. - -If you have a `Native\Laravel\ChildProcess` instance, you may call the `restart` method on it: - -```php -$tail->stop(); -``` - -Alternatively, you may use the `ChildProcess` facade to restart a process via its alias: - -```php -ChildProcess::restart('tail'); -``` - ## Handling output A Child Process may send output via any of the following interfaces: From 7fc6072eab7955a8e776a0be1b1cfc89e8d0aaf5 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Fri, 1 Nov 2024 09:34:45 +0000 Subject: [PATCH 9/9] Copy tweaks --- .../views/docs/1/digging-deeper/child-process.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/resources/views/docs/1/digging-deeper/child-process.md b/resources/views/docs/1/digging-deeper/child-process.md index 1d14888a..8db38476 100644 --- a/resources/views/docs/1/digging-deeper/child-process.md +++ b/resources/views/docs/1/digging-deeper/child-process.md @@ -135,7 +135,7 @@ ChildProcess::start( ### PHP scripts -For your convenience NativePHP provides a simple method to execute PHP scripts with in the background using NativePHP's packaged PHP binary: +For your convenience, NativePHP provides a simple method to execute PHP scripts in the background using NativePHP's packaged PHP binary: ```php ChildProcess::php('path/to/script.php', alias: 'script'); @@ -143,7 +143,7 @@ ChildProcess::php('path/to/script.php', alias: 'script'); ### Artisan commands -NativePHP provides a similar method to run artisan commands: +NativePHP provides a similar method convenience for Artisan commands: ```php ChildProcess::artisan('smtp:serve', alias: 'smtp-server'); @@ -191,7 +191,8 @@ ChildProcess::stop('tail'); This will attempt to stop the process gracefully. The [`ProcessExited`](#codeprocessexitedcode) event will be dispatched if the process exits. -Note that [persistent processes](/docs/1/digging-deeper/child-process#persistent-processes) restart when you stop them manually. The only way to stop a persistent process is by quitting the application. +Note that [persistent processes](/docs/1/digging-deeper/child-process#persistent-processes) will restart even when you +stop them manually. The only way to stop a persistent process is by quitting the application. ## Restarting a Child Process @@ -273,9 +274,11 @@ A Child Process may send output via any of the following interfaces: - A custom interface, e.g. a network socket. - Broadcasting a Custom Event -`STDOUT`, `STDERR` & [Custom Events](/docs/1/digging-deeper/broadcasting#custom-events) are dispatched using Laravel's event system. +`STDOUT`, `STDERR` & [Custom Events](/docs/1/digging-deeper/broadcasting#custom-events) are dispatched using +Laravel's event system. -You may listen to these events by registering a listener in your app service provider, or on the front end using the [Native helper](/docs/1/digging-deeper/broadcasting#listening-with-javascript). +You may listen to these events by registering a listener in your app service provider, or on the front end +using the [Native helper](/docs/1/digging-deeper/broadcasting#listening-with-javascript). Please see the [Events](#events) section for a full list of events.