Skip to content

Commit 40aef96

Browse files
committed
make WebSocket Send + Sync
1 parent 304e109 commit 40aef96

5 files changed

Lines changed: 283 additions & 181 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Thumbs.db
99
# Rust
1010
/Cargo.lock
1111
/target
12+
/.cargo
1213

1314
# wasm example
1415
/examples/wasm/dist

Cargo.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ json = ["dep:serde", "dep:serde_json"]
2424

2525
[dependencies]
2626
# pin version, see https://github.com/jgraef/reqwest-websocket/pull/33
27-
futures-util = { version = ">=0.3.31", default-features = false, features = ["sink"] }
27+
futures-util = { version = ">=0.3.31", default-features = false, features = ["sink", "async-await-macro"] }
28+
futures-channel = { version = "0.3", default-features = false, features = ["sink", "std"] }
2829
reqwest = { version = "0.12", default-features = false }
2930
thiserror = "2"
3031
tracing = "0.1"
@@ -38,14 +39,13 @@ tungstenite = { version = "0.24", default-features = false, features = ["handsha
3839

3940
[target.'cfg(target_arch = "wasm32")'.dependencies]
4041
web-sys = { version = "0.3", features = ["WebSocket", "CloseEvent", "ErrorEvent", "Event", "MessageEvent", "BinaryType"] }
41-
tokio = { version = "1", default-features = false, features = ["sync", "macros"] }
42+
wasm-bindgen-futures = "0.4"
4243

4344
[dev-dependencies]
4445
tokio = { version = "1", features = ["macros", "rt"] }
4546
reqwest = { version = "0.12", features = ["default-tls"] }
4647
serde = { version = "1.0", features = ["derive"] }
47-
futures-util = { version = "0.3", default-features = false, features = ["sink", "alloc"] }
48+
futures-util = "0.3"
4849

4950
[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
5051
wasm-bindgen-test = "0.3"
51-
wasm-bindgen-futures = "0.4"

examples/wasm/src/app.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ pub fn App() -> impl IntoView {
1717

1818
spawn_local(async move {
1919
let websocket = reqwest_websocket::websocket("https://echo.websocket.org/").await.unwrap();
20+
tracing::info!("WebSocket connected");
21+
2022
let (mut sender, mut receiver) = websocket.split();
2123

2224
futures::join!(

src/lib.rs

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ pub enum Error {
8585
#[cfg(target_arch = "wasm32")]
8686
#[cfg_attr(docsrs, doc(cfg(target_arch = "wasm32")))]
8787
#[error("web_sys error")]
88-
WebSys(#[from] wasm::WebSysError),
88+
WebSys(#[from] wasm::Error),
8989

9090
/// Error during serialization/deserialization.
9191
#[error("serde_json error")]
@@ -178,7 +178,7 @@ impl UpgradedRequestBuilder {
178178
let inner = native::send_request(self.inner, &self.protocols).await?;
179179

180180
#[cfg(target_arch = "wasm32")]
181-
let inner = wasm::WebSysWebSocketStream::new(self.inner.build()?, &self.protocols).await?;
181+
let inner = wasm::WebSocket::new(self.inner.build()?, &self.protocols).await?;
182182

183183
Ok(UpgradeResponse {
184184
inner,
@@ -198,7 +198,7 @@ pub struct UpgradeResponse {
198198
inner: native::WebSocketResponse,
199199

200200
#[cfg(target_arch = "wasm32")]
201-
inner: wasm::WebSysWebSocketStream,
201+
inner: wasm::WebSocket,
202202

203203
#[allow(dead_code)]
204204
protocols: Vec<String>,
@@ -229,7 +229,7 @@ impl UpgradeResponse {
229229

230230
#[cfg(target_arch = "wasm32")]
231231
let (inner, protocol) = {
232-
let protocol = self.inner.protocol();
232+
let protocol = self.inner.protocol().to_owned();
233233
(self.inner, Some(protocol))
234234
};
235235

@@ -252,7 +252,7 @@ pub struct WebSocket {
252252
inner: native::WebSocketStream,
253253

254254
#[cfg(target_arch = "wasm32")]
255-
inner: wasm::WebSysWebSocketStream,
255+
inner: wasm::WebSocket,
256256

257257
protocol: Option<String>,
258258
}
@@ -283,7 +283,15 @@ impl WebSocket {
283283
}
284284

285285
#[cfg(target_arch = "wasm32")]
286-
self.inner.close(code.into(), reason.unwrap_or_default())?;
286+
{
287+
let mut inner = self.inner;
288+
inner
289+
.send(Message::Close {
290+
code,
291+
reason: reason.unwrap_or_default().to_owned(),
292+
})
293+
.await?;
294+
}
287295

288296
Ok(())
289297
}
@@ -344,8 +352,22 @@ pub mod tests {
344352
#[cfg(target_arch = "wasm32")]
345353
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
346354

355+
use crate::{UpgradeResponse, UpgradedRequestBuilder};
356+
347357
use super::{websocket, CloseCode, Message, RequestBuilderExt, WebSocket};
348358

359+
macro_rules! assert_send {
360+
($ty:ty) => {
361+
const _: () = {
362+
struct Assert<T: Send>(std::marker::PhantomData<T>);
363+
Assert::<$ty>(std::marker::PhantomData);
364+
};
365+
};
366+
}
367+
368+
// unfortunately hyper IO is not sync
369+
assert_send!(WebSocket);
370+
349371
async fn test_websocket(mut websocket: WebSocket) {
350372
let text = "Hello, World!";
351373
websocket
@@ -467,4 +489,10 @@ pub mod tests {
467489
assert_eq!(byte, 1001u16);
468490
assert_eq!(u16::from(text), 1001u16);
469491
}
492+
493+
// assert that our types are Send + Sync
494+
trait AssertSendSync: Send + Sync {}
495+
impl AssertSendSync for UpgradedRequestBuilder {}
496+
impl AssertSendSync for UpgradeResponse {}
497+
impl AssertSendSync for WebSocket {}
470498
}

0 commit comments

Comments
 (0)