clean up main
This commit is contained in:
parent
ac6604a5a5
commit
b19075f252
1 changed files with 83 additions and 76 deletions
159
src/main.rs
159
src/main.rs
|
@ -1,101 +1,33 @@
|
||||||
use serde_json::Result;
|
use futures_channel::mpsc::{unbounded, UnboundedSender};
|
||||||
use std::fs;
|
use futures_util::{future, pin_mut, stream::TryStreamExt, SinkExt, StreamExt};
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
env,
|
env,
|
||||||
|
error::Error,
|
||||||
|
fs,
|
||||||
net::SocketAddr,
|
net::SocketAddr,
|
||||||
|
result::Result,
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
|
|
||||||
use futures_channel::mpsc::{unbounded, UnboundedSender};
|
|
||||||
use futures_util::{future, pin_mut, stream::TryStreamExt, StreamExt};
|
|
||||||
|
|
||||||
use tokio::net::{TcpListener, TcpStream};
|
use tokio::net::{TcpListener, TcpStream};
|
||||||
use tokio_tungstenite::tungstenite::protocol::Message;
|
use tokio_tungstenite::tungstenite::protocol::Message;
|
||||||
|
|
||||||
type Tx = UnboundedSender<Message>;
|
type Tx = UnboundedSender<Message>;
|
||||||
type PeerMap = Arc<Mutex<HashMap<SocketAddr, Tx>>>;
|
type PeerMap = Arc<Mutex<HashMap<SocketAddr, Tx>>>;
|
||||||
|
|
||||||
async fn handle_connection(peer_map: PeerMap, raw_stream: TcpStream, addr: SocketAddr) {
|
|
||||||
println!("Incoming TCP connection from: {}", addr);
|
|
||||||
|
|
||||||
let ws_stream = tokio_tungstenite::accept_async(raw_stream)
|
|
||||||
.await
|
|
||||||
.expect("Error during the websocket handshake occurred");
|
|
||||||
println!("WebSocket connection established: {}", addr);
|
|
||||||
|
|
||||||
// Insert the write part of this peer to the peer map.
|
|
||||||
let (tx, rx) = unbounded();
|
|
||||||
peer_map.lock().unwrap().insert(addr, tx);
|
|
||||||
|
|
||||||
let (outgoing, incoming) = ws_stream.split();
|
|
||||||
|
|
||||||
let broadcast_incoming = incoming.try_for_each(|msg| {
|
|
||||||
println!(
|
|
||||||
"Received a message from {}: {}",
|
|
||||||
addr,
|
|
||||||
msg.to_text().unwrap()
|
|
||||||
);
|
|
||||||
let peers = peer_map.lock().unwrap();
|
|
||||||
|
|
||||||
// We want to broadcast the message to everyone except ourselves.
|
|
||||||
let broadcast_recipients = peers
|
|
||||||
.iter()
|
|
||||||
.filter(|(peer_addr, _)| peer_addr != &&addr)
|
|
||||||
.map(|(_, ws_sink)| ws_sink);
|
|
||||||
|
|
||||||
for recp in broadcast_recipients {
|
|
||||||
recp.unbounded_send(msg.clone()).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
future::ok(())
|
|
||||||
});
|
|
||||||
|
|
||||||
let receive_from_others = rx.map(Ok).forward(outgoing);
|
|
||||||
|
|
||||||
pin_mut!(broadcast_incoming, receive_from_others);
|
|
||||||
future::select(broadcast_incoming, receive_from_others).await;
|
|
||||||
|
|
||||||
println!("{} disconnected", &addr);
|
|
||||||
peer_map.lock().unwrap().remove(&addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::main]
|
|
||||||
async fn main() -> Result<()> {
|
|
||||||
test()?;
|
|
||||||
|
|
||||||
let addr = env::args()
|
|
||||||
.nth(1)
|
|
||||||
.unwrap_or_else(|| "127.0.0.1:8080".to_string());
|
|
||||||
|
|
||||||
let state = PeerMap::new(Mutex::new(HashMap::new()));
|
|
||||||
|
|
||||||
// Create the event loop and TCP listener we'll accept connections on.
|
|
||||||
let try_socket = TcpListener::bind(&addr).await;
|
|
||||||
let listener = try_socket.expect("Failed to bind");
|
|
||||||
println!("\nListening on: {}", addr);
|
|
||||||
|
|
||||||
// Let's spawn the handling of each connection in a separate task.
|
|
||||||
while let Ok((stream, addr)) = listener.accept().await {
|
|
||||||
tokio::spawn(handle_connection(state.clone(), stream, addr));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub mod CAHd_game;
|
pub mod CAHd_game;
|
||||||
use crate::CAHd_game::*;
|
use crate::CAHd_game::*;
|
||||||
|
|
||||||
/// Parse json for card data
|
/// Parse json for card data
|
||||||
fn load_json(path: &str) -> Result<Vec<CAHCardSet>> {
|
fn load_json(path: &str) -> Result<Vec<CAHCardSet>, Box<dyn Error>> {
|
||||||
let data: String = fs::read_to_string(path).expect("Error reading file");
|
let data: String = fs::read_to_string(path).expect("Error reading file");
|
||||||
let jayson: Vec<CAHCardSet> = serde_json::from_str(&data)?;
|
let jayson: Vec<CAHCardSet> = serde_json::from_str(&data)?;
|
||||||
|
|
||||||
Ok(jayson)
|
Ok(jayson)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test() -> Result<()> {
|
fn test() -> Result<(), Box<dyn Error>> {
|
||||||
// choose decks
|
// choose decks
|
||||||
let cards_input_path: &str = "data/cah-cards-full.json";
|
let cards_input_path: &str = "data/cah-cards-full.json";
|
||||||
|
|
||||||
|
@ -140,6 +72,81 @@ fn test() -> Result<()> {
|
||||||
println!("----------------------");
|
println!("----------------------");
|
||||||
for card in &games[0].players[0].white {
|
for card in &games[0].players[0].white {
|
||||||
println!("{}", card.text);
|
println!("{}", card.text);
|
||||||
};
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn handle_connection(
|
||||||
|
peer_map: PeerMap,
|
||||||
|
raw_stream: TcpStream,
|
||||||
|
addr: SocketAddr,
|
||||||
|
) -> Result<(), tokio_tungstenite::tungstenite::Error> {
|
||||||
|
println!("Incoming TCP connection from: {}", addr);
|
||||||
|
|
||||||
|
let ws_stream = tokio_tungstenite::accept_async(raw_stream).await?;
|
||||||
|
println!("WebSocket connection established: {}", addr);
|
||||||
|
|
||||||
|
// Insert the write part of this peer to the peer map.
|
||||||
|
let (tx, rx) = unbounded();
|
||||||
|
|
||||||
|
peer_map.lock().unwrap().insert(addr, tx);
|
||||||
|
|
||||||
|
let (mut sink, stream) = ws_stream.split();
|
||||||
|
|
||||||
|
sink.send(Message::Text("hey".to_string())).await?;
|
||||||
|
|
||||||
|
let broadcast_incoming = stream.try_for_each(|msg| {
|
||||||
|
println!(
|
||||||
|
"Received a message from {}: {}",
|
||||||
|
addr,
|
||||||
|
msg.to_text().unwrap()
|
||||||
|
);
|
||||||
|
let peers = peer_map.lock().unwrap();
|
||||||
|
|
||||||
|
// We want to broadcast the message to everyone except ourselves.
|
||||||
|
let broadcast_recipients = peers
|
||||||
|
.iter()
|
||||||
|
.filter(|(peer_addr, _)| peer_addr != &&addr)
|
||||||
|
.map(|(_, ws_sink)| ws_sink);
|
||||||
|
|
||||||
|
for recp in broadcast_recipients {
|
||||||
|
recp.unbounded_send(msg.clone()).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
future::ok(())
|
||||||
|
});
|
||||||
|
|
||||||
|
let receive_from_others = rx.map(Ok).forward(sink);
|
||||||
|
|
||||||
|
pin_mut!(broadcast_incoming, receive_from_others);
|
||||||
|
future::select(broadcast_incoming, receive_from_others).await;
|
||||||
|
|
||||||
|
println!("{} disconnected", &addr);
|
||||||
|
peer_map.lock().unwrap().remove(&addr);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
test()?;
|
||||||
|
|
||||||
|
let addr = env::args()
|
||||||
|
.nth(1)
|
||||||
|
.unwrap_or_else(|| "127.0.0.1:8080".to_string());
|
||||||
|
|
||||||
|
let state = PeerMap::new(Mutex::new(HashMap::new()));
|
||||||
|
|
||||||
|
// Create the event loop and TCP listener we'll accept connections on.
|
||||||
|
let try_socket = TcpListener::bind(&addr).await;
|
||||||
|
let listener = try_socket?;
|
||||||
|
|
||||||
|
println!("\nListening on: {}", addr);
|
||||||
|
|
||||||
|
// Let's spawn the handling of each connection in a separate task.
|
||||||
|
while let Ok((stream, addr)) = listener.accept().await {
|
||||||
|
tokio::spawn(handle_connection(state.clone(), stream, addr));
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue