Skip to content

Commit 143d430

Browse files
committed
fix(websocket-websys): Add support for different WASM environments
Add support different WASM environments (such as workers, NodeJS) that don't have a `window` global. This is done by introducing a `WebContext` `enum` that abstracts and detects the `Window` vs the `WorkerGlobalScope` API. This is done due to the `web-sys` lack of interes to support this (see discussion in [this issue](rustwasm/wasm-bindgen#1046)).
1 parent 7f4ba69 commit 143d430

File tree

5 files changed

+34
-18
lines changed

5 files changed

+34
-18
lines changed

Cargo.lock

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ libp2p-webrtc = { version = "0.6.1-alpha", path = "transports/webrtc" }
109109
libp2p-webrtc-utils = { version = "0.1.0", path = "misc/webrtc-utils" }
110110
libp2p-webrtc-websys = { version = "0.2.0-alpha", path = "transports/webrtc-websys" }
111111
libp2p-websocket = { version = "0.43.0", path = "transports/websocket" }
112-
libp2p-websocket-websys = { version = "0.3.0", path = "transports/websocket-websys" }
112+
libp2p-websocket-websys = { version = "0.3.1", path = "transports/websocket-websys" }
113113
libp2p-webtransport-websys = { version = "0.2.0", path = "transports/webtransport-websys" }
114114
libp2p-yamux = { version = "0.45.0", path = "muxers/yamux" }
115115
multiaddr = "0.18.0"

transports/websocket-websys/CHANGELOG.md

+7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
## 0.3.1
2+
3+
- Add support for different WASM environments by introducing a `WebContext` that
4+
detects and abstracts the `Window` vs the `WorkerGlobalScope` API. See [PR 4889].
5+
6+
[PR 4889]: https://github.com/libp2p/rust-libp2p/pull/4889
7+
18
## 0.3.0
29

310

transports/websocket-websys/Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name = "libp2p-websocket-websys"
33
edition = "2021"
44
rust-version = "1.60.0"
55
description = "WebSocket for libp2p under WASM environment"
6-
version = "0.3.0"
6+
version = "0.3.1"
77
authors = ["Vince Vasta <[email protected]>"]
88
license = "MIT"
99
repository = "https://github.com/libp2p/rust-libp2p"
@@ -20,7 +20,7 @@ parking_lot = "0.12.1"
2020
send_wrapper = "0.6.0"
2121
thiserror = "1.0.50"
2222
wasm-bindgen = "0.2.88"
23-
web-sys = { version = "0.3.65", features = ["BinaryType", "CloseEvent", "MessageEvent", "WebSocket", "Window"] }
23+
web-sys = { version = "0.3.65", features = ["BinaryType", "CloseEvent", "MessageEvent", "WebSocket", "Window", "WorkerGlobalScope"] }
2424

2525
# Passing arguments to the docsrs builder in order to properly document cfg's.
2626
# More information: https://docs.rs/about/builds#cross-compiling

transports/websocket-websys/src/lib.rs

+23-14
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
//! Libp2p websocket transports built on [web-sys](https://rustwasm.github.io/wasm-bindgen/web-sys/index.html).
2222
23+
mod web_context;
24+
2325
use bytes::BytesMut;
2426
use futures::task::AtomicWaker;
2527
use futures::{future::Ready, io, prelude::*};
@@ -35,7 +37,17 @@ use std::sync::atomic::{AtomicBool, Ordering};
3537
use std::sync::Mutex;
3638
use std::{pin::Pin, task::Context, task::Poll};
3739
use wasm_bindgen::{prelude::*, JsCast};
38-
use web_sys::{window, CloseEvent, Event, MessageEvent, WebSocket};
40+
use web_sys::{CloseEvent, Event, MessageEvent, WebSocket};
41+
42+
use crate::web_context::WebContext;
43+
44+
/// Arbitrary, maximum amount we are willing to buffer before we throttle our user.
45+
const MAX_BUFFER: usize = 1024 * 1024;
46+
47+
thread_local! {
48+
/// Global web context for abstracting the `Window` vs the `WorkerGlobalScope` API
49+
static GLOBAL_WEB_CONTEXT: WebContext = WebContext::new();
50+
}
3951

4052
/// A Websocket transport that can be used in a wasm environment.
4153
///
@@ -61,9 +73,6 @@ pub struct Transport {
6173
_private: (),
6274
}
6375

64-
/// Arbitrary, maximum amount we are willing to buffer before we throttle our user.
65-
const MAX_BUFFER: usize = 1024 * 1024;
66-
6776
impl libp2p_core::Transport for Transport {
6877
type Output = Connection;
6978
type Error = Error;
@@ -300,13 +309,14 @@ impl Connection {
300309
}
301310
}
302311
});
303-
let buffered_amount_low_interval = window()
304-
.expect("to have a window")
305-
.set_interval_with_callback_and_timeout_and_arguments(
306-
on_buffered_amount_low_closure.as_ref().unchecked_ref(),
307-
100, // Chosen arbitrarily and likely worth tuning. Due to low impact of the /ws transport, no further effort was invested at the time.
308-
&Array::new(),
309-
)
312+
let buffered_amount_low_interval = GLOBAL_WEB_CONTEXT
313+
.with(|g| {
314+
g.set_interval_with_callback_and_timeout_and_arguments(
315+
on_buffered_amount_low_closure.as_ref().unchecked_ref(),
316+
100, // Chosen arbitrarily and likely worth tuning. Due to low impact of the /ws transport, no further effort was invested at the time.
317+
&Array::new(),
318+
)
319+
})
310320
.expect("to be able to set an interval");
311321

312322
Self {
@@ -439,8 +449,7 @@ impl Drop for Connection {
439449
.close_with_code_and_reason(GO_AWAY_STATUS_CODE, "connection dropped");
440450
}
441451

442-
window()
443-
.expect("to have a window")
444-
.clear_interval_with_handle(self.inner.buffered_amount_low_interval)
452+
GLOBAL_WEB_CONTEXT
453+
.with(|g| g.clear_interval_with_handle(self.inner.buffered_amount_low_interval));
445454
}
446455
}

0 commit comments

Comments
 (0)