Communication Channels
Using the channel-type
meta variable of the webr
filter
As you dive deeper into using webR, it’s crucial to grasp how webR manages communication between R and your web browser. Think of it as a conversation between two active workers or “threads”:
- Web Browser: This is your web browser, like Chrome or Firefox, which you use to surf the internet and interact with web pages.
- webR: This is like a dedicated helper that specializes in running R code. It operates separately from your main web browser.
Now, here’s why this separation is so important: webR’s special version of R can tackle complicated and time-consuming calculations without causing your web browser to freeze or become unresponsive when you’re on a web page that uses webR.
Imagine trying to watch a video online while your computer is running a heavy software update. Without separating them, your video might start buffering, freeze, or even crash. But by putting the update in the background (on a separate worker, like webR), your video can continue to play smoothly. It’s the same concept with webR and your web browser – keeping things running smoothly without hiccups.
For more details, please see the official webR documentation on Worker Communication and Serving Web Pages with webR.
Communication Channels: How Web Browser and webR Talk
Now, let’s explore how your main web browser and the webR worker thread communicate with each other. They use what we call “communication channels” to swap information. Think of it like like passing notes between two people, but in a high-tech way.
There are a few different types of communication channels available:
- “automatic” or
0
(Default):- Requirements: Your setup should be prepared for either
"shared-array-buffer"
or"post-message"
. - Limitations: It’s not clear which option is being used.
- Requirements: Your setup should be prepared for either
- “shared-array-buffer” or
1
:- Requirements: This option requires something called “cross-origin isolation,” which you can read more about here.
- Limitations: There aren’t any significant limitations to worry about.
- “service-worker” or
2
:- Requirements: You need to have JavaScript service workers set up, like
webr-serviceworker.js
andwebr-worker.js
. - Limitations: The script for the service worker must be on the same website as the one using WebR.
- Requirements: You need to have JavaScript service workers set up, like
- “post-message” or
3
:- Requirements: No special requirements are needed for this option.
- Limitations: R code can’t be interrupted easily. Some advanced R features, like nested R REPLs, might not work as expected.
When you start using WebR, it usually picks the best communication channel for you. However, you can manually choose a channel type if needed. Just remember that each option comes with its own set of requirements and limitations, so pick the one that suits your project best.
In simpler terms, it’s like choosing the right tool for the job. Depending on what you’re doing, you might use different methods to pass messages between your web browser and webR.
Specifying How webR Communicates
In a Quarto document’s YAML header, you can tell webR which communication channel to use by setting the channel-type
option. It’s like telling webR how you want it to talk with your web browser. For example, if you want to use the "post-message"
channel, you can do it like this:
---
title: "Setting Up webR to use the PostMessage Channel"
format: html
webr:
channel-type: "post-message"
filters:
- webr
---
Your Communication Channel Choices
The remainder of the document describes the different communication methods alongside ways to satisfy the requirements.
Using “automatic” for Communication (Default)
By default, the quarto-webr
extension guides webR to use the "automatic"
option for channel-type
, if you don’t specify the channel-type
in your document’s YAML header. Let’s break down how this default setting works:
- Communication Attempts: webR will try two different communication channels in order:
- First, it attempts to establish a communication channel using
"shared-array-buffer"
. - If that doesn’t work, it will then try to use
"post-message"
.
- First, it attempts to establish a communication channel using
- Fallback Behavior: If both of these attempts are unsuccessful, webR code cells in your document will be shown in a deactivated state. This means they won’t run or execute any R code.
It’s important to note that the "automatic"
option doesn’t try to use the "service-worker"
option for communication.
In summary, when you leave the channel-type
unspecified, webR will follow the "automatic"
option, attempting to use "shared-array-buffer"
and then "post-message"
. If both attempts fail, your webR code cells will be inactive.
Using “service-worker” for Communication
Here, we’ll dive into the "service-worker"
option for communication.
The "service-worker"
option doesn’t work with Quarto Pub. If you’re hosting documents with Quarto Pub, please use the channel-type: "post-message"
option instead. There’s an ongoing effort to address the service worker upload issue with the Quarto team, which you can track here.
When you set channel-type
to "service-worker"
, webR changes its communication channel to use the Service Worker API. This means you need two worker scripts, webr-worker.js
and webr-serviceworker.js
, hosted on the same website as the page using webR.
Here’s what you need to ensure:
1. Worker Scripts: The quarto-webr
extension will automatically create and register these workers when your Quarto document is rendered.
2. Directory Structure: Your initial directory structure should include these files:
.
├── _extensions/coatless/webr
└── demo-quarto-webr.qmd
After rendering the Quarto document with the "service-worker"
option, your directory will look like this:
.
├── _extensions/coatless/webr
├── demo-quarto-webr.qmd
├── demo-quarto-webr.html # Rendered document
├── webr-serviceworker.js # Service workers
└── webr-worker.js
3. Hosting: When hosting your rendered document, you need to make sure the rendered HTML document and the service worker files (webr-serviceworker.js
and webr-worker.js
) are present on the server. This is important for everything to work correctly:
.
├── demo-quarto-webr.html # Rendered document
├── webr-serviceworker.js # Service workers
└── webr-worker.js
If you want to change where the service workers are located, you can set the service-worker-url
option in the document YAML. By default, the rendered document will search for the service workers in its current directory.
In a nutshell, the “service-worker” option is a powerful choice for communication with webR, but you need to ensure the correct setup and hosting to make it work smoothly.
Using “post-message” for Communication
Now, let’s delve into the "post-message"
option. This sets up a communication channel using something called Post Message. It’s a good choice when you can’t use cross-isolation or service workers. This option is simpler to set up and works in more places, like RStudio’s preview pane or the built-in browser in VSCode.
However, there are some trade-offs. While it’s easier to get started, certain R features that need to pause and wait for input (like readline()
, menu()
, browser()
, etc.) won’t work as expected. Instead, they’ll return empty values like ""
or c('', '')
. Also, you won’t have the option to stop or interrupt long-running R code. In those cases, you’ll need to refresh the page to regain control.
Feel free to experiment with the "post-message"
interface in this webR code cell:
This Quarto extension is open source software and is not affiliated with Posit, Quarto, or webR. The extension is at best a community effort to simplify the integration of webR inside of Quarto generated documents.