Skip to content

Commit bc98afc

Browse files
jsdanielhsisou
andcommitted
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 by binding to the global `setInterval` and `clearInterval` functions directly. This uses the same approach as used by gloo-timers implemented in [rustwasm/gloo#185](rustwasm/gloo#185) and [rustwasm/gloo#283](rustwasm/gloo#283) given the `web-sys` lack of interes to support this (see discussion in [this issue](rustwasm/wasm-bindgen#1046)). Co-authored-by: sisou <[email protected]>
1 parent 0ceb658 commit bc98afc

File tree

3 files changed

+27
-12
lines changed

3 files changed

+27
-12
lines changed

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 binding to the global
4+
`setInterval` and `clearInterval` functions directly. 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

+1-1
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"

transports/websocket-websys/src/lib.rs

+19-11
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
use bytes::BytesMut;
2424
use futures::task::AtomicWaker;
2525
use futures::{future::Ready, io, prelude::*};
26-
use js_sys::Array;
26+
use js_sys::Function;
2727
use libp2p_core::{
2828
multiaddr::{Multiaddr, Protocol},
2929
transport::{ListenerId, TransportError, TransportEvent},
@@ -35,7 +35,16 @@ use std::sync::atomic::{AtomicBool, Ordering};
3535
use std::sync::Mutex;
3636
use std::{pin::Pin, task::Context, task::Poll};
3737
use wasm_bindgen::{prelude::*, JsCast};
38-
use web_sys::{window, CloseEvent, Event, MessageEvent, WebSocket};
38+
use web_sys::{CloseEvent, Event, MessageEvent, WebSocket};
39+
40+
#[wasm_bindgen]
41+
extern "C" {
42+
#[wasm_bindgen(js_name = "setInterval", catch)]
43+
fn set_interval(handler: &Function, timeout: i32) -> Result<JsValue, JsValue>;
44+
45+
#[wasm_bindgen(js_name = "clearInterval")]
46+
fn clear_interval(handle: JsValue) -> JsValue;
47+
}
3948

4049
/// A Websocket transport that can be used in a wasm environment.
4150
///
@@ -188,7 +197,7 @@ struct Inner {
188197
_on_close_closure: Rc<Closure<dyn FnMut(CloseEvent)>>,
189198
_on_error_closure: Rc<Closure<dyn FnMut(CloseEvent)>>,
190199
_on_message_closure: Rc<Closure<dyn FnMut(MessageEvent)>>,
191-
buffered_amount_low_interval: i32,
200+
buffered_amount_low_interval: Option<JsValue>,
192201
}
193202

194203
impl Inner {
@@ -300,14 +309,13 @@ 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(
312+
let buffered_amount_low_interval = Some(
313+
set_interval(
306314
on_buffered_amount_low_closure.as_ref().unchecked_ref(),
307315
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(),
309316
)
310-
.expect("to be able to set an interval");
317+
.expect("to be able to set an interval"),
318+
);
311319

312320
Self {
313321
inner: SendWrapper::new(Inner {
@@ -439,8 +447,8 @@ impl Drop for Connection {
439447
.close_with_code_and_reason(GO_AWAY_STATUS_CODE, "connection dropped");
440448
}
441449

442-
window()
443-
.expect("to have a window")
444-
.clear_interval_with_handle(self.inner.buffered_amount_low_interval)
450+
if let Some(id) = self.inner.buffered_amount_low_interval.take() {
451+
clear_interval(id);
452+
}
445453
}
446454
}

0 commit comments

Comments
 (0)