nuke everything and start a new cargo project
parent
c017fcc516
commit
40c95eaa5c
@ -1,2 +1 @@
|
|||||||
target/
|
/target
|
||||||
Cargo.lock
|
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jade"
|
||||||
|
version = "0.1.0"
|
@ -1,31 +1,3 @@
|
|||||||
mod mods;
|
fn main() {
|
||||||
use std::{collections::HashMap, convert::Infallible, sync::Arc, env};
|
println!("Hello, world!");
|
||||||
use tokio::sync::{mpsc, Mutex};
|
|
||||||
use warp::{ws::Message, Filter, Rejection};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Client {
|
|
||||||
pub client_id: String,
|
|
||||||
pub sender: Option<mpsc::UnboundedSender<std::result::Result<Message, warp::Error>>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
type Clients = Arc<Mutex<HashMap<String, Client>>>;
|
|
||||||
type Result<T> = std::result::Result<T, Rejection>;
|
|
||||||
|
|
||||||
#[tokio::main]
|
|
||||||
async fn main() {
|
|
||||||
let clients: Clients = Arc::new(Mutex::new(HashMap::new()));
|
|
||||||
println!("Configuring websocket route");
|
|
||||||
let ws_route = warp::path("ws")
|
|
||||||
.and(warp::ws())
|
|
||||||
.and(with_clients(clients.clone()))
|
|
||||||
.and_then(mods::handlers::ws_handler);
|
|
||||||
|
|
||||||
let routes = ws_route.with(warp::cors().allow_any_origin());
|
|
||||||
println!("Starting server");
|
|
||||||
warp::serve(routes).run(([127, 0, 0, 1], 8080)).await;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn with_clients(clients: Clients) -> impl Filter<Extract = (Clients,), Error = Infallible> + Clone {
|
|
||||||
warp::any().map(move || clients.clone())
|
|
||||||
}
|
}
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
pub mod handlers;
|
|
||||||
pub mod ws;
|
|
@ -1,8 +0,0 @@
|
|||||||
use crate::{mods::ws, Clients, Result};
|
|
||||||
use warp::Reply;
|
|
||||||
|
|
||||||
pub async fn ws_handler(ws: warp::ws::Ws, clients: Clients) -> Result<impl Reply> {
|
|
||||||
println!("ws_handler");
|
|
||||||
|
|
||||||
Ok(ws.on_upgrade(move |socket| ws::client_connection(socket, clients)))
|
|
||||||
}
|
|
@ -1,63 +0,0 @@
|
|||||||
use crate::{Client, Clients};
|
|
||||||
use futures::{FutureExt, StreamExt};
|
|
||||||
use tokio::sync::mpsc;
|
|
||||||
use tokio_stream::wrappers::UnboundedReceiverStream;
|
|
||||||
use uuid::Uuid;
|
|
||||||
use warp::ws::{Message, WebSocket};
|
|
||||||
|
|
||||||
|
|
||||||
pub async fn client_connection(ws: WebSocket, clients: Clients) {
|
|
||||||
println!("establishing client connection... {:?}", ws);
|
|
||||||
|
|
||||||
let (client_ws_sender, mut client_ws_rcv) = ws.split();
|
|
||||||
let (client_sender, client_rcv) = mpsc::unbounded_channel();
|
|
||||||
|
|
||||||
let client_rcv = UnboundedReceiverStream::new(client_rcv);
|
|
||||||
|
|
||||||
tokio::task::spawn(client_rcv.forward(client_ws_sender).map(|result| {
|
|
||||||
if let Err(e) = result {
|
|
||||||
println!("error sending websocket msg: {}", e);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
let uuid = Uuid::new_v4().simple().to_string();
|
|
||||||
|
|
||||||
let new_client = Client {
|
|
||||||
client_id: uuid.clone(),
|
|
||||||
sender: Some(client_sender),
|
|
||||||
};
|
|
||||||
|
|
||||||
clients.lock().await.insert(uuid.clone(), new_client);
|
|
||||||
while let Some(result) = client_ws_rcv.next().await {
|
|
||||||
let msg = match result {
|
|
||||||
Ok(msg) => msg,
|
|
||||||
Err(e) => {
|
|
||||||
println!("error receiving message for id {}): {}", uuid.clone(), e);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
client_msg(&uuid, msg, &clients).await;
|
|
||||||
}
|
|
||||||
clients.lock().await.remove(&uuid);
|
|
||||||
println!("{} disconnected", uuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn client_msg(client_id: &str, msg: Message, clients: &Clients) {
|
|
||||||
println!("received message from {}: {:?}", client_id, msg);
|
|
||||||
|
|
||||||
let message = match msg.to_str() {
|
|
||||||
Ok(v) => v,
|
|
||||||
Err(_) => return,
|
|
||||||
};
|
|
||||||
let locked = clients.lock().await;
|
|
||||||
match locked.get(client_id) {
|
|
||||||
Some(v) => {
|
|
||||||
if let Some(sender) = &v.sender {
|
|
||||||
println!("sending pong");
|
|
||||||
let _ = sender.send(Ok(Message::text(message)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => return,
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
Loading…
Reference in New Issue