Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ jobs:
- webworker
- webworker-gloo
- webworker-module
- webworker-module-sharedworker
- wasm_threads
- yew
- yew-tailwindcss
Expand Down
155 changes: 155 additions & 0 deletions examples/webworker-module-sharedworker/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions examples/webworker-module-sharedworker/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[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",
"SharedWorkerGlobalScope",
"MessageEvent",
"SharedWorker",
"WorkerOptions",
"WorkerType",
"MessagePort",
] }
3 changes: 3 additions & 0 deletions examples/webworker-module-sharedworker/Trunk.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[build]
target = "index.html"
dist = "dist"
14 changes: 14 additions & 0 deletions examples/webworker-module-sharedworker/index.html
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>
43 changes: 43 additions & 0 deletions examples/webworker-module-sharedworker/src/bin/app.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
use wasm_bindgen::{prelude::*, JsCast};
use web_sys::{MessageEvent, SharedWorker, WorkerOptions, WorkerType};

fn worker_new(url: &str) -> SharedWorker {
let mut options = WorkerOptions::new();
options.type_(WorkerType::Module);
options.name("example shared worker");
SharedWorker::new_with_worker_options(url, &options).expect("failed to spawn worker")
}

fn main() {
console_error_panic_hook::set_once();

let worker = worker_new("./worker_loader.js");

// FIX: When creating the first worker connection withn SharedWorker(...)
// the spec described connect event in worker processing model
// does not reach the worker's onconnect handler.
// > 13. If is shared is true, then queue a global task on the DOM manipulation
// > task source given worker global scope to fire an event named connect at
// > worker global scope, using MessageEvent, with the data attribute
// > initialized to the empty string, the ports attribute initialized to
// > a new frozen array containing inside port, and the source attribute
// > initialized to inside port.
// (https://html.spec.whatwg.org/multipage/workers.html#worker-processing-model)
// This means that only subsequent worker connections reach that handler
// because SharedWorkerGlobalScope is already initialized
// (https://html.spec.whatwg.org/multipage/workers.html#shared-workers-and-the-sharedworker-interface)

let onmessage = Closure::wrap(Box::new(move |msg: MessageEvent| {
web_sys::console::log_2(
&"webpage received message from worker".into(),
&JsValue::from(msg),
);
}) as Box<dyn FnMut(MessageEvent)>);

let port = worker.port();
port.set_onmessage(Some(onmessage.as_ref().unchecked_ref()));
onmessage.forget();

port.post_message(&"Hello from webpage".into())
.expect("Successfully queing a message to be handled by worker");
}
37 changes: 37 additions & 0 deletions examples/webworker-module-sharedworker/src/bin/worker.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use wasm_bindgen::{prelude::*, JsCast};
use web_sys::{MessageEvent, MessagePort, SharedWorkerGlobalScope};

fn main() {
console_error_panic_hook::set_once();
web_sys::console::log_1(&"worker starting".into());

let scope = SharedWorkerGlobalScope::from(JsValue::from(js_sys::global()));

let onconnect = Closure::wrap(Box::new(move |msg: MessageEvent| {
web_sys::console::log_2(&"got connect".into(), &JsValue::from(&msg));

let port = msg.ports().get(0);
let port = port.dyn_ref::<MessagePort>().unwrap();

let callback = Closure::wrap(Box::new(|msg: MessageEvent| {
web_sys::console::log_2(
&"Received message from website".into(),
&JsValue::from(&msg),
);
let target = msg.target().expect("message event should have a target");
let port = target
.dyn_ref::<MessagePort>()
.expect("message event target should be the port which sent the message");
port.post_message(&"thank you for the message".into())
.expect("worker should be able to send a message back");
}) as Box<dyn FnMut(MessageEvent)>);

port.add_event_listener_with_callback("message", callback.as_ref().unchecked_ref())
.unwrap_throw();
callback.forget();
port.start(); // this is requred when not using port.onmessage both for worker and webpage
}) as Box<dyn FnMut(MessageEvent)>);

scope.set_onconnect(Some(onconnect.as_ref().unchecked_ref()));
onconnect.forget();
}
Loading