-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Wasm build target #85
base: main
Are you sure you want to change the base?
Changes from 13 commits
63e8b53
f9677a1
ab53dbc
b9fdeb9
979b5bb
0bfd370
401c7be
4a02876
7d946df
b1e85fb
ee0db23
2ecbe5d
44e1ce6
d556e08
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,3 +8,7 @@ Cargo.lock | |
|
||
# These are backup files generated by rustfmt | ||
**/*.rs.bk | ||
|
||
.idea/ | ||
|
||
pkg/ |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,15 +28,15 @@ use { | |
oneshot, | ||
}, | ||
}; | ||
pub use { | ||
fetch::*, | ||
inbound::*, | ||
outbound::*, | ||
stream::*, | ||
tokio_tungstenite::tungstenite::protocol::CloseFrame, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. CloseFrame from tokio_tungstenite has different structure when wasm |
||
}; | ||
|
||
pub use {fetch::*, inbound::*, outbound::*, stream::*}; | ||
#[cfg(not(target_arch = "wasm32"))] | ||
pub type TransportError = tokio_tungstenite::tungstenite::Error; | ||
#[cfg(not(target_arch = "wasm32"))] | ||
pub use tokio_tungstenite::tungstenite::protocol::CloseFrame; | ||
#[cfg(target_arch = "wasm32")] | ||
pub type TransportError = tokio_tungstenite_wasm::Error; | ||
#[cfg(target_arch = "wasm32")] | ||
pub use tokio_tungstenite_wasm::CloseFrame; | ||
|
||
#[derive(Debug, thiserror::Error)] | ||
pub enum WebsocketClientError { | ||
|
@@ -52,6 +52,9 @@ pub enum WebsocketClientError { | |
#[error("Websocket transport error: {0}")] | ||
Transport(TransportError), | ||
|
||
#[error("Url error: {0}")] | ||
HttpErr(http::Error), | ||
|
||
#[error("Not connected")] | ||
NotConnected, | ||
} | ||
|
@@ -146,7 +149,12 @@ impl Client { | |
{ | ||
let (control_tx, control_rx) = mpsc::unbounded_channel(); | ||
|
||
tokio::spawn(connection_event_loop(control_rx, handler)); | ||
let fut = connection_event_loop(control_rx, handler); | ||
#[cfg(target_arch = "wasm32")] | ||
wasm_bindgen_futures::spawn_local(fut); | ||
|
||
#[cfg(not(target_arch = "wasm32"))] | ||
tokio::spawn(fut); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No support for |
||
|
||
Self { control_tx } | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,12 @@ | ||
#[cfg(not(target_arch = "wasm32"))] | ||
use tokio_tungstenite::{ | ||
connect_async, | ||
tungstenite::{protocol::CloseFrame, Message}, | ||
MaybeTlsStream, | ||
WebSocketStream, | ||
}; | ||
#[cfg(target_arch = "wasm32")] | ||
use tokio_tungstenite_wasm::{connect as connect_async, CloseFrame, Message, WebSocketStream}; | ||
use { | ||
super::{ | ||
inbound::InboundRequest, | ||
|
@@ -17,26 +26,22 @@ use { | |
pin::Pin, | ||
task::{Context, Poll}, | ||
}, | ||
tokio::{ | ||
net::TcpStream, | ||
sync::{ | ||
mpsc, | ||
mpsc::{UnboundedReceiver, UnboundedSender}, | ||
oneshot, | ||
}, | ||
}, | ||
tokio_tungstenite::{ | ||
connect_async, | ||
tungstenite::{protocol::CloseFrame, Message}, | ||
MaybeTlsStream, | ||
WebSocketStream, | ||
tokio::sync::{ | ||
mpsc, | ||
mpsc::{UnboundedReceiver, UnboundedSender}, | ||
oneshot, | ||
}, | ||
}; | ||
|
||
#[cfg(not(target_arch = "wasm32"))] | ||
pub type SocketStream = WebSocketStream<MaybeTlsStream<TcpStream>>; | ||
#[cfg(not(target_arch = "wasm32"))] | ||
use tokio::net::TcpStream; | ||
#[cfg(target_arch = "wasm32")] | ||
pub type SocketStream = WebSocketStream; | ||
|
||
/// Opens a connection to the Relay and returns [`ClientStream`] for the | ||
/// connection. | ||
#[cfg(not(target_arch = "wasm32"))] | ||
pub async fn create_stream(request: HttpRequest<()>) -> Result<ClientStream, WebsocketClientError> { | ||
let (socket, _) = connect_async(request) | ||
.await | ||
|
@@ -45,6 +50,16 @@ pub async fn create_stream(request: HttpRequest<()>) -> Result<ClientStream, Web | |
Ok(ClientStream::new(socket)) | ||
} | ||
|
||
#[cfg(target_arch = "wasm32")] | ||
pub async fn create_stream(request: HttpRequest<()>) -> Result<ClientStream, WebsocketClientError> { | ||
let url = format!("{}", request.uri()); | ||
let socket = connect_async(url) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
.await | ||
.map_err(WebsocketClientError::ConnectionFailed)?; | ||
|
||
Ok(ClientStream::new(socket)) | ||
} | ||
|
||
/// Possible events produced by the [`ClientStream`]. | ||
/// | ||
/// The events are produced by polling [`ClientStream`] in a loop. | ||
|
@@ -140,6 +155,7 @@ impl ClientStream { | |
} | ||
|
||
/// Closes the connection. | ||
#[cfg(not(target_arch = "wasm32"))] | ||
pub async fn close(&mut self, frame: Option<CloseFrame<'static>>) -> Result<(), ClientError> { | ||
self.close_frame = frame.clone(); | ||
self.socket | ||
|
@@ -148,6 +164,15 @@ impl ClientStream { | |
.map_err(|err| WebsocketClientError::ClosingFailed(err).into()) | ||
} | ||
|
||
#[cfg(target_arch = "wasm32")] | ||
pub async fn close(&mut self, frame: Option<CloseFrame<'static>>) -> Result<(), ClientError> { | ||
self.close_frame = frame.clone(); | ||
self.socket | ||
.close() | ||
.await | ||
.map_err(|err| WebsocketClientError::ClosingFailed(err).into()) | ||
} | ||
|
||
fn parse_inbound(&mut self, result: Result<Message, TransportError>) -> Option<StreamEvent> { | ||
match result { | ||
Ok(message) => match &message { | ||
|
@@ -223,7 +248,7 @@ impl ClientStream { | |
self.close_frame = frame.clone(); | ||
Some(StreamEvent::ConnectionClosed(frame.clone())) | ||
} | ||
|
||
#[cfg(not(target_arch = "wasm32"))] | ||
_ => None, | ||
}, | ||
|
||
|
@@ -269,6 +294,7 @@ impl Stream for ClientStream { | |
type Item = StreamEvent; | ||
|
||
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> { | ||
#[cfg(not(target_arch = "wasm32"))] | ||
if self.socket.is_terminated() { | ||
return Poll::Ready(None); | ||
} | ||
|
@@ -300,9 +326,15 @@ impl Stream for ClientStream { | |
} | ||
|
||
impl FusedStream for ClientStream { | ||
#[cfg(not(target_arch = "wasm32"))] | ||
fn is_terminated(&self) -> bool { | ||
self.socket.is_terminated() | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No access to TcpSocket, so cannot determine if connected |
||
#[cfg(target_arch = "wasm32")] | ||
fn is_terminated(&self) -> bool { | ||
false | ||
} | ||
} | ||
|
||
impl Drop for ClientStream { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -67,7 +67,7 @@ impl Default for JwtHeader<'_> { | |
} | ||
} | ||
|
||
impl<'a> JwtHeader<'a> { | ||
impl JwtHeader<'_> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Clippy warned me about this |
||
pub fn is_valid(&self) -> bool { | ||
self.typ == JWT_HEADER_TYP && self.alg == JWT_HEADER_ALG | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
[package] | ||
name = "wasm_websocket_demo" | ||
version = "0.1.0" | ||
edition = "2021" | ||
authors = ["WalletConnect Team"] | ||
license = "Apache-2.0" | ||
|
||
[build] | ||
target = "wasm32-unknown-uknown" | ||
|
||
[lib] | ||
crate-type = ["cdylib"] | ||
|
||
[dependencies] | ||
anyhow = "1" | ||
data-encoding = "2" | ||
futures = "0.3" | ||
rand = "0.8.5" | ||
getrandom = { version = "0.2", features = ["js"] } | ||
wasm-bindgen = { version = "0.2", features = ["serde-serialize"] } | ||
wasm-bindgen-futures = "0.4" | ||
web-sys = { version = "0.3", features = [ | ||
"Element", "HtmlElement", "Window", | ||
"WebSocket", "console", "Event", | ||
"Document", "Crypto", "CryptoKey", | ||
"DateTimeValue", "SubtleCrypto", "Performance", | ||
"TimeEvent" | ||
] } | ||
walletconnect_sdk = { path = "../" } | ||
console_error_panic_hook = { version = "0.1" } | ||
web-time = { version = "1", features = ["serde"] } | ||
gloo-timers = { version = "0.3", features = ["futures"] } | ||
|
||
[package.metadata.wasm-pack.profile.dev] | ||
wasm-bindgen = { debug-js-glue = true, demangle-name-section = true } | ||
wasm-opt = false | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# Wasm Websocket Client Example | ||
|
||
## Quickstart | ||
|
||
1. Set the PROJECT_ID env: | ||
|
||
```shell | ||
export PROJECT_ID="my-project-id" | ||
``` | ||
|
||
2. Install wasm-pack | ||
|
||
```shell | ||
cargo install wasm-pack | ||
``` | ||
|
||
3. Install basic-http-server | ||
|
||
```shell | ||
cargo install basic-http-server | ||
``` | ||
|
||
4. Build | ||
|
||
```shell | ||
wasm-pack build --target web --dev | ||
``` | ||
|
||
Visit [http://localhost:4000](http://localhost:4000) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tokio_tungstenite::tungstenite::client::IntoClientRequest,
is not available in wasm target