1 个不稳定版本
0.7.0 | 2021 年 5 月 24 日 |
---|
#105 在 WebSocket
4,465 每月下载量
用于 fluvio
56KB
694 行
ws_stream_wasm
在 WASM 中使用 WebSocket 的便捷库
这是对 ws_stream_wasm 的分支,它为 Clone
添加了对 WsStream
的支持,这可能会导致或不会导致内存泄漏。
WebSocket 的 web-sys 绑定不便于直接使用。这个 crate 希望解决这个问题。浏览器无法创建直接的 TCP 连接,通过在 WebSocket 上放置 AsyncRead/
AsyncWrite
,我们可以在浏览器内部使用任何异步字节流的工作接口。该 crate 有 2 个主要类型。存在 WsMeta
类型,以便在将 WsStream
传递给接收流所有权的组合器时访问 Web API。
功能
WsMeta
:web_sys::WebSocket
的包装器。WsMessage
: WebSocket 消息的简单 Rust 表示。WsStream
:一个 futuresSink
/Stream
的WsMessage
。它还包含一个方法into_io()
,允许您获取一个实现了AsyncRead
/AsyncWrite
/AsyncBufRead
(在 tokio 的tokio_io
功能之后)的包装器。WsEvent
:通过WsMeta
使用 pharos 可观察事件(主要用于连接关闭)。
注意:这个包只适用于WASM。如果您需要一个在WebSocket上实现 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
。这样您就可以使用它们与在WASM上也工作的通用库,但这些库需要连接是 Send
。目前WASM没有线程,我们使用的底层类型大多数也不是 Send
。目前的解决方案是使用 send_wrapper::SendWrapper
。如果它在创建它的线程之外被解引用,则会引发panic。您必须考虑到类型不是 Send
,但在WASM上将其传递给需要 Send
的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点“不可接受的行为”中描述的任何行为都不受欢迎,并可能导致您被禁止。如果任何人都未能尊重这些/您的限制,包括项目的维护者和版主,您有权将其指出。
许可
依赖关系
~8–11MB
~216K SLoC