Skip to content

Commit

Permalink
add trunk
Browse files Browse the repository at this point in the history
  • Loading branch information
Its-Just-Nans committed May 13, 2024
1 parent 6629215 commit f6d612e
Show file tree
Hide file tree
Showing 11 changed files with 186 additions and 131 deletions.
16 changes: 9 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,29 @@ This is a simple [WebSocket](https://en.wikipedia.org/wiki/WebSocket) library fo
## Usage

``` rust
let (mut sender, receiver) = ewebsock::connect("ws://example.com").unwrap();
let options = ewebsock::Options::default();
// add header and subprotocol to options
let (mut sender, receiver) = ewebsock::connect("ws://example.com", options).unwrap();
sender.send(ewebsock::WsMessage::Text("Hello!".into()));
while let Some(event) = receiver.try_recv() {
println!("Received {:?}", event);
}
```

## Testing

First start the example echo server with:

```sh
cargo r -p echo_server
```

Then test the native library with:
Then test the library with:

```sh
# native mode
cargo run -p example_app
```

And the web library with:
```sh
./example_app/start_server.sh &
./example_app/build_web.sh --open
# web mode
cd example_app/ && trunk serve
```
2 changes: 1 addition & 1 deletion ewebsock/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ log = "0.4"

# native:
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
tungstenite = { version = "0.22" }
tungstenite = { git = "https://github.com/snapview/tungstenite-rs" }

# Optional dependencies for feature "tokio":
async-stream = { version = "0.3", optional = true }
Expand Down
20 changes: 0 additions & 20 deletions ewebsock/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,26 +43,6 @@ mod web;
#[cfg(target_arch = "wasm32")]
pub use web::*;

/// transfrom uri and options into a request builder
pub fn into_requester(
uri: http::Uri,
options: Options,
) -> tungstenite::client::ClientRequestBuilder {
let mut client_request: tungstenite::ClientRequestBuilder =
tungstenite::client::ClientRequestBuilder::new(uri);
if let Some(headers) = options.additional_headers {
for (key, value) in headers {
client_request = client_request.with_header(key, value);
}
}
if let Some(subprotocols) = options.subprotocols {
for subprotocol in subprotocols {
client_request = client_request.with_sub_protocol(subprotocol);
}
}
client_request
}

// ----------------------------------------------------------------------------

/// A web-socket message.
Expand Down
40 changes: 31 additions & 9 deletions ewebsock/src/native_tungstenite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,26 @@ use std::{

use crate::{EventHandler, Options, Result, WsEvent, WsMessage};

/// transfrom uri and options into a request builder
pub fn into_requester(
uri: http::Uri,
options: Options,
) -> tungstenite::client::ClientRequestBuilder {
let mut client_request: tungstenite::client::ClientRequestBuilder =
tungstenite::client::ClientRequestBuilder::new(uri);
if let Some(headers) = options.additional_headers {
for (key, value) in headers {
client_request = client_request.with_header(key, value);
}
}
if let Some(subprotocols) = options.subprotocols {
for subprotocol in subprotocols {
client_request = client_request.with_sub_protocol(subprotocol);
}
}
client_request
}

/// This is how you send [`WsMessage`]s to the server.
///
/// When the last clone of this is dropped, the connection is closed.
Expand Down Expand Up @@ -70,17 +90,19 @@ pub(crate) fn ws_receive_impl(url: String, options: Options, on_event: EventHand
/// All errors are returned to the caller, and NOT reported via `on_event`.
pub fn ws_receiver_blocking(url: &str, options: Options, on_event: &EventHandler) -> Result<()> {
let uri: http::Uri = url.parse().unwrap();
let builder = tungstenite::ClientRequestBuilder::new(uri).with_header("Origin", url);
let config = tungstenite::protocol::WebSocketConfig::from(options);
let config = tungstenite::protocol::WebSocketConfig::from(options.clone());
let max_redirects = 3; // tungstenite default

let (mut socket, response) =
match tungstenite::client::connect_with_config(builder, Some(config), max_redirects) {
Ok(result) => result,
Err(err) => {
return Err(format!("Connect: {err}"));
}
};
let (mut socket, response) = match tungstenite::client::connect_with_config(
crate::into_requester(uri, options),
Some(config),
max_redirects,
) {
Ok(result) => result,
Err(err) => {
return Err(format!("Connect: {err}"));
}
};

log::debug!("WebSocket HTTP response code: {}", response.status());
log::trace!(
Expand Down
1 change: 1 addition & 0 deletions example_app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dist/
5 changes: 1 addition & 4 deletions example_app/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@ include = ["../LICENSE-APACHE", "../LICENSE-MIT", "**/*.rs", "Cargo.toml"]
publish = false


[lib]
crate-type = ["cdylib", "rlib"]


[features]
default = []

Expand All @@ -25,6 +21,7 @@ ewebsock = { path = "../ewebsock", features = ["tls"] }

eframe = "0.26.2" # Gives us egui, epi and web+native backends
log = "0.4"
env_logger = "0.10"

# native:
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
Expand Down
75 changes: 0 additions & 75 deletions example_app/build_web.sh

This file was deleted.

115 changes: 115 additions & 0 deletions example_app/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
<!DOCTYPE html>
<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<!-- Disable zooming: -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />

<head>
<!-- change this to your project name -->
<title>ewebsock demo</title>

<!-- config for our rust wasm binary. go to https://trunkrs.dev/assets/#rust for more customization -->
<link data-trunk rel="rust" data-wasm-opt="2" />
<!-- this is the base url relative to which other urls will be constructed. trunk will insert this from the public-url option -->
<base data-trunk-public-url />

<link rel="manifest" href="manifest.json" />
<meta name="theme-color" media="(prefers-color-scheme: light)" content="white" />
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="#404040" />

<style>
html {
/* Remove touch delay: */
touch-action: manipulation;
}

body {
/* Light mode background color for what is not covered by the egui canvas,
or where the egui canvas is translucent. */
background: #909090;
}

@media (prefers-color-scheme: dark) {
body {
/* Dark mode background color for what is not covered by the egui canvas,
or where the egui canvas is translucent. */
background: #404040;
}
}

/* Allow canvas to fill entire web page: */
html,
body {
overflow: hidden;
margin: 0 !important;
padding: 0 !important;
height: 100%;
width: 100%;
}

/* Position canvas in center-top: */
canvas {
margin-right: auto;
margin-left: auto;
display: block;
position: absolute;
top: 0%;
left: 50%;
transform: translate(-50%, 0%);
}

.centered {
margin-right: auto;
margin-left: auto;
display: block;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: #f0f0f0;
font-size: 24px;
font-family: Ubuntu-Light, Helvetica, sans-serif;
text-align: center;
}

/* ---------------------------------------------- */
/* Loading animation from https://loading.io/css/ */
.lds-dual-ring {
display: inline-block;
width: 24px;
height: 24px;
}

.lds-dual-ring:after {
content: " ";
display: block;
width: 24px;
height: 24px;
margin: 0px;
border-radius: 50%;
border: 3px solid #fff;
border-color: #fff transparent #fff transparent;
animation: lds-dual-ring 1.2s linear infinite;
}

@keyframes lds-dual-ring {
0% {
transform: rotate(0deg);
}

100% {
transform: rotate(360deg);
}
}
</style>
</head>

<body>
<!-- The WASM code will resize the canvas dynamically -->
<!-- the id is hardcoded in main.rs . so, make sure both match. -->
<canvas id="the_canvas_id"></canvas>
</body>
</html>

<!-- Powered by egui: https://github.com/emilk/egui/ -->
12 changes: 0 additions & 12 deletions example_app/setup_web.sh

This file was deleted.

24 changes: 23 additions & 1 deletion example_app/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ async fn main() -> eframe::Result<()> {
fn main() -> eframe::Result<()> {
main_impl()
}

// When compiling natively:
#[cfg(not(target_arch = "wasm32"))]
fn main_impl() -> Result<(), eframe::Error> {
env_logger::init(); // Log to stderr (if you run with `RUST_LOG=debug`).

Expand All @@ -24,3 +25,24 @@ fn main_impl() -> Result<(), eframe::Error> {
Box::new(|_cc| Box::new(app)),
)
}

// When compiling to web using trunk:
#[cfg(target_arch = "wasm32")]
fn main_impl() -> Result<(), eframe::Error> {
// Redirect `log` message to `console.log` and friends:
eframe::WebLogger::init(log::LevelFilter::Debug).ok();

let web_options = eframe::WebOptions::default();

wasm_bindgen_futures::spawn_local(async {
eframe::WebRunner::new()
.start(
"the_canvas_id", // hardcode it
web_options,
Box::new(|_cc| Box::new(example_app::ExampleApp::default())),
)
.await
.expect("failed to start eframe");
});
Ok(())
}
Loading

0 comments on commit f6d612e

Please sign in to comment.