15个不稳定版本 (3个重大变更)
0.6.1 | 2024年6月15日 |
---|---|
0.6.0 | 2024年6月15日 |
0.5.3 | 2024年6月11日 |
0.4.5 | 2024年5月24日 |
0.3.2 | 2023年11月8日 |
#151 in Web编程
每月下载量:80,275
43KB
557 行
tokio_with_wasm
使用Rinf测试
tokio_with_wasm
是一个为网页浏览器设计的Rust库,提供了tokio
的功能。它旨在为Web应用提供与tokio
完全相同的特性,利用JavaScript网页API。
这个库由模拟真实tokio
行为的JavaScript粘合代码组成。由于tokio_with_wasm
没有自己的运行时并且适应JavaScript事件循环,所以tokio
的高级特性可能无法正常工作。
当使用spawn_blocking()
时,会自动调整网页工作线程的数量以适应并行任务的数量。请参阅文档以获取更多信息。
此库假定您使用wasm-pack
和wasm-bindgen
编译Rust项目,目前使用的是wasm32-unknown-unknown
的Rust目标。请注意,这个库目前只支持wasm-bindgen
的web
目标,不支持如no-modules
之类的其他目标。
特性
-
熟悉的API:如果您熟悉
tokio
,您会对tokio_with_wasm
感到非常熟悉。它提供了类似的功能,并遵循相同的模式来启动和管理异步任务。 -
Web Worker集成:
tokio_with_wasm
通过底层使用Web API来适应JavaScript环境。这意味着您可以为Web应用编写并发且高效的Rust代码。 -
启动异步和阻塞任务:您可以启动异步和阻塞任务。异步任务允许您执行非阻塞操作,而阻塞任务适用于计算密集型或同步任务。
虽然将来可以添加各种I/O功能,但目前尚未包含。
使用方法
将此库添加到您的 Cargo.toml
文件中,与 tokio
并列。
[dependencies]
tokio = { version = "0.0.0", features = ["rt"] }
tokio_with_wasm = { version = "0.0.0", features = ["rt"] }
以下是一个使用 tokio_with_wasm
的简单示例。
use tokio_with_wasm::alias as tokio;
#[cfg_attr(target_family = "wasm", wasm_bindgen(start))]
#[cfg_attr(not(target_family = "wasm"), tokio::main(flavor = "current_thread"))]
async fn main() {
let async_join_handle = tokio::spawn(async {
// Your asynchronous code here.
// This will run concurrently
// in the same web worker(thread).
});
let blocking_join_handle = tokio::task::spawn_blocking(|| {
// Your blocking code here.
// This will run parallelly
// in the external pool of web workers.
});
let async_result = async_join_handle.await;
let blocking_result = blocking_join_handle.await;
for i in 1..1000 {
// Some repeating task here
// that shouldn't block the JavaScript runtime.
tokio::task::yield_now().await;
}
}
use tokio_with_wasm::alias as tokio;
语句在功能上等同于下面的代码。这个导入提供了便利,并且可以缩短代码。
#[cfg(all(
target_arch = "wasm32",
target_vendor = "unknown",
target_os = "unknown"
))]
use tokio_with_wasm as tokio;
#[cfg(not(all(
target_arch = "wasm32",
target_vendor = "unknown",
target_os = "unknown"
)))]
use tokio;
文档
API 文档可以在 docs.rs 上找到。
注意
请记住,您绝对不应该编写会引发恐慌的代码。
对于 wasm32-unknown-unknown
,目前 没有方法 来捕获和回滚像在本地平台那样的恐慌。恐慌最终会导致泄露 JavaScript Promise
。
尽可能使用 Result
枚举。
部署 Web 应用
在构建您的 WebAssembly 模块并准备部署后,请确保您的 Web 服务器已配置为在响应中包含与跨源相关的 HTTP 标头。将 Cross-Origin-Opener-Policy
设置为 same-origin
,并将 Cross-Origin-Embedder-Policy
设置为 require-corp
。这些标头允许使用您的网站的客户端访问 SharedArrayBuffer
Web API,这类似于网络上的共享内存。此外,不要忘记在服务器配置中指定 application/wasm
MIME 类型,以确保 .wasm
文件的最佳性能。
为什么需要这样做
由于网络沙盒环境的存在,网络有诸多限制,这阻止了线程、时间、文件 I/O、网络 I/O 等许多原生功能的的使用。因此,由于这些限制,Rust 的 std
中缺少某些功能。这就是为什么 tokio
在 Web 浏览器上并不真正有效的原因。
为了解决这个问题,这个包提供了与原始原生模块同名 的 tokio
模块,为这些限制提供了解决方案。
未来愿景
由于 Rust 的许多 Web 生态系统目前基于 wasm32-unknown-unknown
,我们不得不创建 tokio
的别名包,以便直接在 Web 上使用其功能。
希望,当 wasm32-wasi
成为网络的主流 Rust 目标时,jco
可能会成为 wasm-bindgen
的替代品,因为它可以通过浏览器模拟(polyfills)提供完整的 std
功能。然而,这需要时间,因为 wasi-threads
建议还有很长的路要走。
在此之前,我们有 tokio_with_wasm
!
贡献指南
我们始终欢迎贡献!如果您有任何建议、错误报告或想要为 tokio_with_wasm
的开发做出贡献,请打开一个问题或提交一个拉取请求。
存在一些情况,您不能直接在网络上使用原生Rust代码。这是因为wasm32-unknown-unknown
Rust目标,它是通过wasm-bindgen
使用的,并没有完整的std
模块。请参考以下链接了解如何使用wasm-bindgen
与JavaScript交互。
- https://wasm.rust-lang.net.cn/wasm-bindgen/reference/attributes/on-js-imports/js_name.html
- https://wasm.rust-lang.net.cn/wasm-bindgen/reference/attributes/on-js-imports/js_namespace.html
Rust代码可以在Web Worker中被调用。因此,我们无法像在JavaScript的主线程中工作那样访问全局的window
JavaScript对象。请参考以下链接检查在Web Worker中可用的Web API。您可能会对现代JavaScript的各种功能感到惊讶。
请注意,这个库使用了一种相当简单和原始的方法来模拟原生tokio
功能。这是因为这个库被视为在wasm32-wasi
之前的临时解决方案。只要能让事物在网络上正常工作,任何类型的PR都是可能的。
依赖项
~9–13MB
~223K SLoC