Connected the websocket to the state
This commit is contained in:
parent
2bd3d03955
commit
a6d06350ab
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -122,9 +122,11 @@ checksum = "130aac562c0dd69c56b3b1cc8ffd2e17be31d0b6c25b61c96b76231aa23e39e1"
|
|||||||
name = "carrier-signal"
|
name = "carrier-signal"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"futures",
|
||||||
"legion",
|
"legion",
|
||||||
"rand 0.7.3",
|
"rand 0.7.3",
|
||||||
"serde",
|
"serde",
|
||||||
|
"serde_json",
|
||||||
"tera",
|
"tera",
|
||||||
"tokio",
|
"tokio",
|
||||||
"warp",
|
"warp",
|
||||||
|
@ -8,9 +8,11 @@ license = "AGPL-3.0-or-later"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
futures = { version = "0.3", default-features = false, features = ["alloc"] }
|
||||||
legion = "0.2.1"
|
legion = "0.2.1"
|
||||||
rand = "0.7.3"
|
rand = "0.7.3"
|
||||||
serde = { version = "1.0", features= ["derive"] }
|
serde = { version = "1.0", features= ["derive"] }
|
||||||
|
serde_json = "1.0"
|
||||||
tera = "1"
|
tera = "1"
|
||||||
tokio = { version = "0.2", features = ["full"] }
|
tokio = { version = "0.2", features = ["full"] }
|
||||||
warp = "0.2"
|
warp = "0.2"
|
51
src/main.rs
51
src/main.rs
@ -1,12 +1,13 @@
|
|||||||
mod simulation;
|
mod simulation;
|
||||||
mod state;
|
mod state;
|
||||||
|
|
||||||
use std::convert::Infallible;
|
use std::{convert::Infallible, sync::Arc};
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
|
use futures::SinkExt;
|
||||||
|
use serde_json::json;
|
||||||
use tera::{Context, Tera};
|
use tera::{Context, Tera};
|
||||||
use tokio::sync::watch;
|
use tokio::sync::watch;
|
||||||
use warp::Filter;
|
use warp::{Filter, ws::{Message, WebSocket}};
|
||||||
|
|
||||||
use simulation::Simulation;
|
use simulation::Simulation;
|
||||||
use state::State;
|
use state::State;
|
||||||
@ -29,26 +30,58 @@ async fn main() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
let tr = Arc::new(tr);
|
let tr = Arc::new(tr);
|
||||||
let tera = move |with_template| render(with_template, tr.clone());
|
let tera = move || {
|
||||||
|
let tr = tr.clone();
|
||||||
|
move |with_template| render(with_template, tr.clone())
|
||||||
|
};
|
||||||
|
let state = move || {
|
||||||
|
let state_channel = state_channel.clone();
|
||||||
|
move || state_channel.clone()
|
||||||
|
};
|
||||||
|
|
||||||
let sim = tokio::spawn(async move {
|
let sim = tokio::spawn(async move {
|
||||||
simulation.run().await;
|
simulation.run().await;
|
||||||
});
|
});
|
||||||
|
|
||||||
let hello = warp::get().and(warp::path::end())
|
let hello = warp::get()
|
||||||
.map(move || (state_channel.clone()))
|
.and(warp::path::end())
|
||||||
|
.map(state())
|
||||||
.and_then(|channel| async move { get_state(channel).await })
|
.and_then(|channel| async move { get_state(channel).await })
|
||||||
.map(|state| WithTemplate {
|
.map(|state| WithTemplate {
|
||||||
name: "stuff.tera",
|
name: "stuff.tera",
|
||||||
context: Context::from_serialize(state).unwrap()
|
context: Context::from_serialize(state).unwrap(),
|
||||||
})
|
})
|
||||||
.map(tera);
|
.map(tera());
|
||||||
|
|
||||||
let server = tokio::spawn(async move { warp::serve(hello).run(([127, 0, 0, 1], 3030)).await });
|
let wsstate = state();
|
||||||
|
let ws = warp::path("state")
|
||||||
|
.and(warp::ws())
|
||||||
|
.map(move |ws: warp::ws::Ws| (ws, wsstate()))
|
||||||
|
.map(|(ws, state): (warp::ws::Ws, watch::Receiver<State>)| {
|
||||||
|
ws.on_upgrade(move |websocket| watch_state(websocket, state))
|
||||||
|
});
|
||||||
|
|
||||||
|
let server =
|
||||||
|
tokio::spawn(async move { warp::serve(hello.or(ws)).run(([127, 0, 0, 1], 3030)).await });
|
||||||
|
|
||||||
tokio::try_join!(sim, server).unwrap();
|
tokio::try_join!(sim, server).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn watch_state(mut ws: WebSocket, mut state_channel: watch::Receiver<State>) {
|
||||||
|
loop {
|
||||||
|
let state = state_channel.recv().await;
|
||||||
|
|
||||||
|
let result = match state {
|
||||||
|
Some(state) => ws.send(Message::text(json!(state).to_string())).await,
|
||||||
|
None => ws.send(Message::text("Oh...")).await,
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Err(_) = result {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
async fn get_state(mut channel: watch::Receiver<State>) -> Result<State, Infallible> {
|
async fn get_state(mut channel: watch::Receiver<State>) -> Result<State, Infallible> {
|
||||||
Ok(channel.recv().await.unwrap())
|
Ok(channel.recv().await.unwrap())
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<title>Blab</title>
|
<title>Blab</title>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<h1>Hello, world!</h1>
|
<h1>Hello, world!</h1>
|
||||||
<ul>
|
<ul>
|
||||||
@ -10,5 +11,18 @@
|
|||||||
<li>{{ object.name }} @ {{ object.x }}, {{ object.y }}</li>
|
<li>{{ object.name }} @ {{ object.x }}, {{ object.y }}</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
ws = new WebSocket("ws://localhost:3030/state");
|
||||||
|
|
||||||
|
ws.onopen = function() {
|
||||||
|
console.log("Connected");
|
||||||
|
}
|
||||||
|
|
||||||
|
ws.onmessage = function(e) {
|
||||||
|
console.log("From Server:" + e.data);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user