-
Notifications
You must be signed in to change notification settings - Fork 260
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: add a webworker example using modules
- Loading branch information
Showing
7 changed files
with
303 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
[package] | ||
name = "webworker-module-example" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[dependencies] | ||
console_error_panic_hook = "0.1" | ||
js-sys = "0.3" | ||
wasm-bindgen = "0.2" | ||
web-sys = { version = "0.3", features = [ | ||
"console", | ||
"DedicatedWorkerGlobalScope", | ||
"Document", | ||
"HtmlElement", | ||
"MessageEvent", | ||
"Node", | ||
"Text", | ||
"Url", | ||
"Window", | ||
"Worker", | ||
"WorkerOptions", | ||
"WorkerType", | ||
] } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[build] | ||
target = "index.html" | ||
dist = "dist" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta charset="utf-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1" /> | ||
<title>Trunk | WebWorker | Module</title> | ||
|
||
<base data-trunk-public-url /> | ||
</head> | ||
<body> | ||
<link data-trunk rel="rust" href="Cargo.toml" data-wasm-opt="z" data-bin="app" data-type="main" /> | ||
<link data-trunk rel="rust" href="Cargo.toml" data-wasm-opt="z" data-bin="worker" data-type="worker" data-loader-shim data-bindgen-target="web" /> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
use js_sys::Array; | ||
use wasm_bindgen::{prelude::*, JsCast}; | ||
use web_sys::{MessageEvent, Worker, WorkerOptions, WorkerType}; | ||
|
||
fn worker_new(url: &str) -> Worker { | ||
let mut options = WorkerOptions::new(); | ||
options.type_(WorkerType::Module); | ||
Worker::new_with_options(&url, &options).expect("failed to spawn worker") | ||
} | ||
|
||
fn main() { | ||
console_error_panic_hook::set_once(); | ||
|
||
let worker = worker_new("./worker_loader.js"); | ||
let worker_clone = worker.clone(); | ||
|
||
// NOTE: We must wait for the worker to report that it's ready to receive | ||
// messages. Any message we send beforehand will be discarded / ignored. | ||
// This is different from js-based workers, which can send messages | ||
// before the worker is initialized. | ||
// REASON: This is because javascript only starts processing MessageEvents | ||
// once the worker's script first yields to the javascript event loop. | ||
// For js workers this means that you can register the event listener | ||
// as first thing in the worker and will receive all previously sent | ||
// message events. However, loading wasm is an asynchronous operation | ||
// which yields to the js event loop before the wasm is loaded and had | ||
// a change to register the event listener. At that point js processes | ||
// the message events, sees that there isn't any listener registered, | ||
// and drops them. | ||
|
||
let onmessage = Closure::wrap(Box::new(move |msg: MessageEvent| { | ||
let worker_clone = worker_clone.clone(); | ||
let data = Array::from(&msg.data()); | ||
|
||
if data.length() == 0 { | ||
let msg = Array::new(); | ||
msg.push(&2.into()); | ||
msg.push(&5.into()); | ||
worker_clone | ||
.post_message(&msg.into()) | ||
.expect("sending message to succeed"); | ||
} else { | ||
let a = data | ||
.get(0) | ||
.as_f64() | ||
.expect("first array value to be a number") as u32; | ||
let b = data | ||
.get(1) | ||
.as_f64() | ||
.expect("second array value to be a number") as u32; | ||
let result = data | ||
.get(2) | ||
.as_f64() | ||
.expect("third array value to be a number") as u32; | ||
|
||
web_sys::console::log_1(&format!("{a} x {b} = {result}").into()); | ||
} | ||
}) as Box<dyn Fn(MessageEvent)>); | ||
worker.set_onmessage(Some(onmessage.as_ref().unchecked_ref())); | ||
onmessage.forget(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
use js_sys::Array; | ||
use wasm_bindgen::{prelude::*, JsCast}; | ||
use web_sys::{DedicatedWorkerGlobalScope, MessageEvent}; | ||
|
||
fn main() { | ||
console_error_panic_hook::set_once(); | ||
web_sys::console::log_1(&"worker starting".into()); | ||
|
||
let scope = DedicatedWorkerGlobalScope::from(JsValue::from(js_sys::global())); | ||
let scope_clone = scope.clone(); | ||
|
||
let onmessage = Closure::wrap(Box::new(move |msg: MessageEvent| { | ||
web_sys::console::log_1(&"got message".into()); | ||
|
||
let data = Array::from(&msg.data()); | ||
let a = data | ||
.get(0) | ||
.as_f64() | ||
.expect("first array value to be a number") as u32; | ||
let b = data | ||
.get(1) | ||
.as_f64() | ||
.expect("second array value to be a number") as u32; | ||
|
||
data.push(&(a * b).into()); | ||
scope_clone | ||
.post_message(&data.into()) | ||
.expect("posting result message succeeds"); | ||
}) as Box<dyn Fn(MessageEvent)>); | ||
scope.set_onmessage(Some(onmessage.as_ref().unchecked_ref())); | ||
onmessage.forget(); | ||
|
||
// The worker must send a message to indicate that it's ready to receive messages. | ||
scope | ||
.post_message(&Array::new().into()) | ||
.expect("posting ready message succeeds"); | ||
} |