乐闻世界logo
搜索文章和话题

How do I keep internal state in a WebAssembly module written in Rust?

1个答案

1

Maintaining internal state in WebAssembly modules written in Rust can be achieved through several approaches. Here are the key steps to create and maintain a simple internal state:

Preparation

First, ensure that you have the rustup toolchain installed and the wasm-pack tool installed.

sh
rustup target add wasm32-unknown-unknown cargo install wasm-pack

Writing Rust Code

Next, create a new Cargo project and add the necessary dependencies:

sh
cargo new wasm_state --lib cd wasm_state

Edit the Cargo.toml file to include wasm-bindgen as a dependency:

toml
[lib] crate-type = ["cdylib"] [dependencies] wasm-bindgen = "0.2"

Then, open the src/lib.rs file and implement the Rust code:

rust
use wasm_bindgen::prelude::*; // Use static variables to maintain state static mut COUNTER: i32 = 0; #[wasm_bindgen] pub fn increment() -> i32 { unsafe { // Update the static variable's value COUNTER += 1; COUNTER } } #[wasm_bindgen] pub fn get_counter() -> i32 { unsafe { COUNTER } }

Building the WebAssembly Module

Build the project using wasm-pack to generate a WebAssembly package suitable for web browsers:

sh
wasm-pack build --target web

Using the WebAssembly Module

Now integrate this module into your HTML. For example, create an index.html file with the following HTML and JavaScript:

html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Wasm State Example</title> <script type="module"> import init, { increment, get_counter } from './pkg/wasm_state.js'; async function run() { await init(); document.getElementById("increment").addEventListener("click", () => { increment(); updateCounter(); }); const updateCounter = () => { const count = get_counter(); document.getElementById("counter").textContent = count.toString(); }; updateCounter(); } run(); </script> </head> <body> <p>Counter: <span id="counter"></span></p> <button id="increment">Increment</button> </body> </html>

Replace pkg/wasm_state.js with the actual path to the generated JavaScript glue code for the WebAssembly binding.

Important Considerations

  • Static variables in WebAssembly offer a straightforward method to preserve state across multiple invocations, though thread safety must be addressed in multi-threaded contexts.
  • The unsafe blocks are required because accessing mutable static variables in Rust is inherently unsafe; in production applications, consider alternatives like Mutex or synchronization mechanisms (though these may not be available in WebAssembly).
  • WebAssembly modules cannot directly access browser-provided Web APIs; they rely on JavaScript glue code to handle interactions.
  • To deploy this module in a web application, place the generated WebAssembly package (typically in the pkg/ directory) alongside your index.html on a web server. For local testing, use a Python HTTP server or any static file server.

By following these steps, you can effectively maintain internal state within Rust-written WebAssembly modules and integrate them into web applications.

2024年6月29日 12:07 回复

你的答案