18 个版本
0.7.4 | 2023年1月29日 |
---|---|
0.7.3 | 2021年6月28日 |
0.7.0 | 2021年2月18日 |
0.7.0-beta.1 | 2020年11月3日 |
0.1.0 | 2019年7月19日 |
#5 in WebSocket
198,437 每月下载量
用于 361 个 Crates (直接使用 32 个)
54KB
778 行
ws_stream_wasm
WASM 中使用 WebSocket 的便利库
直接使用 web-sys 绑定的 WebSocket 不太方便。这个 Crates 旨在解决这个问题。浏览器不能创建直接的 TCP 连接,通过在 WebSocket 上放置 AsyncRead
/AsyncWrite
,我们可以在浏览器内部使用任何异步字节流的工作接口。该 Crates 有两种主要类型。存在 WsMeta
类型是为了在将 WsStream
传递给拥有流的所有权组合器的同时访问 Web API。
功能
WsMeta
: 对web_sys::WebSocket
的包装。WsMessage
: WebSocket 消息的简单 Rust 表示。WsStream
:WsMessage
的 futuresSink
/Stream
。它还有一个方法into_io()
,允许你获取一个实现了AsyncRead
/AsyncWrite
/AsyncBufRead
(在 tokio 版本中通过tokio_io
功能) 的包装器。WsEvent
和WsMeta
可以通过 pharos 观察事件(主要用于连接关闭)。
注意:此包仅在WASM上工作。如果您需要实现 AsyncRead
/AsyncWrite
的服务器端等效功能,请查看 ws_stream_tungstenite。
缺少的功能
- 没有自动重连
- 并非所有功能都经过彻底测试。特别是,我对扩展和子协议的使用很少。我使用的 Tungstenite(用于服务器端和自动化测试)不支持这些功能,这使得编写单元测试变得困难。
目录
安装
使用 cargo add: cargo add ws_stream_wasm
使用 cargo yaml
dependencies:
ws_stream_wasm: ^0.7
在 Cargo.toml 中
[dependencies]
ws_stream_wasm = "0.7"
升级
升级时请查看 变更日志。
依赖
此包的依赖项很少。Cargo 会自动为您处理依赖项。
有一个可选功能。启用 tokio_io
功能会导致从 WsStream::into_io
返回的 WsIo
实现tokio版本的AsyncRead/AsyncWrite。
使用方法
集成测试展示了大多数功能的使用情况。示例目录目前没有包含任何有趣的示例。
从编译器的角度来看,此库中的类型是 Send
+ Sync
。这样,您可以将其与也适用于WASM的通用库一起使用,这些库需要连接为 Send
/Sync
。目前WASM没有线程,而我们使用的底层类型大多数不是 Send
。目前的解决方案是使用 send_wrapper::SendWrapper
。如果它在创建它的线程之外被解引用,则会引发恐慌。您必须考虑这些类型不是 Send
,但在WASM上,将其传递给需要 Send
的API是安全的,因为没有太多的多线程支持。因此,将其传递给bindgen executor将是安全的。然而,使用webworkers时,您仍然可以创建额外的线程。责任在于您确保不要尝试在不同的线程上使用Web Api。
您想要使用的主要入口点,例如连接,是 WsMeta::connect
。
基本事件示例
use
{
ws_stream_wasm :: * ,
pharos :: * ,
wasm_bindgen :: UnwrapThrowExt ,
wasm_bindgen_futures :: futures_0_3::spawn_local ,
futures :: stream::StreamExt ,
};
let program = async
{
let (mut ws, _wsio) = WsMeta::connect( "ws://127.0.0.1:3012", None ).await
.expect_throw( "assume the connection succeeds" );
let mut evts = ws.observe( ObserveConfig::default() ).expect_throw( "observe" );
ws.close().await;
// Note that since WsMeta::connect resolves to an opened connection, we don't see
// any Open events here.
//
assert!( evts.next().await.unwrap_throw().is_closing() );
assert!( evts.next().await.unwrap_throw().is_closed () );
};
spawn_local( program );
过滤事件示例
这展示了如何过滤事件。此功能来自 pharos,我们使用它来使 WsMeta
可观察。
use
{
ws_stream_wasm :: * ,
pharos :: * ,
wasm_bindgen :: UnwrapThrowExt ,
wasm_bindgen_futures :: futures_0_3::spawn_local ,
futures :: stream::StreamExt ,
};
let program = async
{
let (mut ws, _wsio) = WsMeta::connect( "ws://127.0.0.1:3012", None ).await
.expect_throw( "assume the connection succeeds" );
// The Filter type comes from the pharos crate.
//
let mut evts = ws.observe( Filter::Pointer( WsEvent::is_closed ).into() ).expect_throw( "observe" );
ws.close().await;
// Note we will only get the closed event here, the WsEvent::Closing has been filtered out.
//
assert!( evts.next().await.unwrap_throw().is_closed () );
};
spawn_local( program );
API
API 文档可以在 docs.rs 上找到。
参考
理解WebSocket以及浏览器如何处理它们的参考文档有
贡献
请查看贡献指南。
测试
为了测试,我们需要后端服务器将数据回显给测试。这些在ws_stream_tungstenite
crate中。
git clone https://github.com/najamelan/ws_stream_tungstenite
cd ws_stream_tungstenite
cargo run --example echo --release
# in a different terminal:
cargo run --example echo_tt --release -- "127.0.0.1:3312"
# the second server is pure async-tungstenite without ws_stream_tungstenite wrapping it in AsyncRead/Write. This
# is needed for testing a WsMessage::Text because ws_stream_tungstenite only does binary.
# in a third terminal, in ws_stream_wasm you have different options:
wasm-pack test --firefox [--headless] [--release]
wasm-pack test --chrome [--headless] [--release]
一般来说,Chrome运行速度更快。在浏览器中运行(不使用--headless
)时,你会在控制台中获得跟踪日志,这有助于调试。在Chrome中,您需要在控制台中启用详细输出,否则只会报告信息和更高级别的信息。
行为准则
在公民行为准则的第4点“不可接受的行为”中描述的任何行为都不受欢迎,可能会让您被禁止。如果任何人都未能尊重这些/您的限制,包括项目的维护者和管理员,您有权指出。
许可
依赖
~7-11MB
~210K SLoC