Refactor network into module, add connection event
This commit is contained in:
parent
f63c184d13
commit
f3e200e91d
4 changed files with 109 additions and 51 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -902,6 +902,7 @@ dependencies = [
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"log",
|
"log",
|
||||||
|
"rand",
|
||||||
"serde 1.0.116",
|
"serde 1.0.116",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
"shipyard",
|
"shipyard",
|
||||||
|
|
17
Cargo.toml
17
Cargo.toml
|
@ -5,15 +5,16 @@ authors = ["Hamcha <hamcha@crunchy.rocks>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tungstenite = "0.11"
|
actix = "0.10"
|
||||||
shipyard = { version = "0.4", features = ["parallel", "serde"] }
|
|
||||||
config = "0.10"
|
config = "0.10"
|
||||||
serde = { version = "1", features = ["derive"] }
|
env_logger = "0.7"
|
||||||
serde_derive = "1"
|
|
||||||
tokio = { version = "0.2", features = ["full"] }
|
|
||||||
tokio-tungstenite = "0.11"
|
|
||||||
futures-util = { version = "0.3", default-features = false, features = ["async-await", "sink", "std"] }
|
futures-util = { version = "0.3", default-features = false, features = ["async-await", "sink", "std"] }
|
||||||
log = { version = "0.4", features = ["std", "serde"] }
|
log = { version = "0.4", features = ["std", "serde"] }
|
||||||
|
rand = "0.7"
|
||||||
|
serde = { version = "1", features = ["derive"] }
|
||||||
|
serde_derive = "1"
|
||||||
|
shipyard = { version = "0.4", features = ["parallel", "serde"] }
|
||||||
|
tokio = { version = "0.2", features = ["full"] }
|
||||||
|
tokio-tungstenite = "0.11"
|
||||||
|
tungstenite = "0.11"
|
||||||
ultraviolet = { version = "0.7", features = [ "f64", "int", "serde" ] }
|
ultraviolet = { version = "0.7", features = [ "f64", "int", "serde" ] }
|
||||||
env_logger = "0.7"
|
|
||||||
actix = "0.10"
|
|
46
src/main.rs
46
src/main.rs
|
@ -1,15 +1,14 @@
|
||||||
mod components;
|
mod components;
|
||||||
mod config;
|
mod config;
|
||||||
|
mod network;
|
||||||
mod systems;
|
mod systems;
|
||||||
|
|
||||||
use crate::config::Settings;
|
use crate::config::Settings;
|
||||||
|
use crate::network::{listen_websocket, NetworkManager};
|
||||||
use actix::prelude::*;
|
use actix::prelude::*;
|
||||||
use env_logger::Env;
|
use env_logger::Env;
|
||||||
use log::info;
|
|
||||||
use shipyard::World;
|
use shipyard::World;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tokio::net::{TcpListener, TcpStream};
|
|
||||||
use tokio_tungstenite::WebSocketStream;
|
|
||||||
|
|
||||||
// Minimum delay between updates, in milliseconds
|
// Minimum delay between updates, in milliseconds
|
||||||
const MIN_UPDATE_MS: u64 = 10;
|
const MIN_UPDATE_MS: u64 = 10;
|
||||||
|
@ -29,24 +28,6 @@ impl Actor for Game {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct NetworkConnection {
|
|
||||||
stream: WebSocketStream<TcpStream>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Actor for NetworkConnection {
|
|
||||||
type Context = Context<NetworkConnection>;
|
|
||||||
|
|
||||||
fn started(&mut self, _ctx: &mut Self::Context) {
|
|
||||||
//TODO Read
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct NetworkManager {}
|
|
||||||
|
|
||||||
impl Actor for NetworkManager {
|
|
||||||
type Context = Context<NetworkManager>;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let env = Env::default().filter_or("LOG_LEVEL", "info");
|
let env = Env::default().filter_or("LOG_LEVEL", "info");
|
||||||
env_logger::init_from_env(env);
|
env_logger::init_from_env(env);
|
||||||
|
@ -54,6 +35,7 @@ fn main() {
|
||||||
let settings = Settings::new().unwrap();
|
let settings = Settings::new().unwrap();
|
||||||
|
|
||||||
let system = System::new("main");
|
let system = System::new("main");
|
||||||
|
|
||||||
Game::create(|_ctx| {
|
Game::create(|_ctx| {
|
||||||
// Create world
|
// Create world
|
||||||
let world = World::default();
|
let world = World::default();
|
||||||
|
@ -64,27 +46,7 @@ fn main() {
|
||||||
Game { world }
|
Game { world }
|
||||||
});
|
});
|
||||||
|
|
||||||
Arbiter::spawn(listen_websocket(settings.bind));
|
NetworkManager::new(settings.bind).start();
|
||||||
|
|
||||||
system.run().unwrap();
|
system.run().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn listen_websocket(bind: String) {
|
|
||||||
let try_socket = TcpListener::bind(&bind).await;
|
|
||||||
let mut listener = try_socket.expect("Failed to bind");
|
|
||||||
info!("Listening on: {}", bind);
|
|
||||||
|
|
||||||
while let Ok((stream, _)) = listener.accept().await {
|
|
||||||
let addr = stream
|
|
||||||
.peer_addr()
|
|
||||||
.expect("connected streams should have a peer address");
|
|
||||||
info!("Peer address: {}", addr);
|
|
||||||
|
|
||||||
let stream = tokio_tungstenite::accept_async(stream)
|
|
||||||
.await
|
|
||||||
.expect("Error during the websocket handshake occurred");
|
|
||||||
info!("New WebSocket connection: {}", addr);
|
|
||||||
|
|
||||||
NetworkConnection::create(|_ctx| NetworkConnection { stream });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
94
src/network.rs
Normal file
94
src/network.rs
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
use actix::prelude::*;
|
||||||
|
use log::info;
|
||||||
|
use rand::prelude::*;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use tokio::net::{TcpListener, TcpStream};
|
||||||
|
use tokio_tungstenite::WebSocketStream;
|
||||||
|
|
||||||
|
pub struct NetworkConnection {
|
||||||
|
conn_id: u64,
|
||||||
|
connected: bool,
|
||||||
|
stream: WebSocketStream<TcpStream>,
|
||||||
|
manager: Addr<NetworkManager>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Actor for NetworkConnection {
|
||||||
|
type Context = Context<NetworkConnection>;
|
||||||
|
|
||||||
|
fn started(&mut self, ctx: &mut Self::Context) {
|
||||||
|
// Send manager my info and get a connection ID assigned
|
||||||
|
let addr = ctx.address();
|
||||||
|
self.manager
|
||||||
|
.send(ClientConnected { addr })
|
||||||
|
.into_actor(self)
|
||||||
|
.then(move |res, act, _| {
|
||||||
|
act.conn_id = res.unwrap();
|
||||||
|
act.connected = true;
|
||||||
|
async {}.into_actor(act)
|
||||||
|
})
|
||||||
|
.wait(ctx);
|
||||||
|
//TODO Start recv/send loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Message)]
|
||||||
|
#[rtype(result = "u64")]
|
||||||
|
struct ClientConnected {
|
||||||
|
addr: Addr<NetworkConnection>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct NetworkManager {
|
||||||
|
bind: String,
|
||||||
|
clients: HashMap<u64, Addr<NetworkConnection>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Actor for NetworkManager {
|
||||||
|
type Context = Context<NetworkManager>;
|
||||||
|
|
||||||
|
fn started(&mut self, ctx: &mut Self::Context) {
|
||||||
|
Arbiter::spawn(listen_websocket(self.bind.clone(), ctx.address()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Handler<ClientConnected> for NetworkManager {
|
||||||
|
type Result = u64;
|
||||||
|
fn handle(&mut self, msg: ClientConnected, _ctx: &mut Self::Context) -> Self::Result {
|
||||||
|
let client_id = rand::thread_rng().gen();
|
||||||
|
self.clients.insert(client_id, msg.addr);
|
||||||
|
client_id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NetworkManager {
|
||||||
|
pub fn new(bind: String) -> Self {
|
||||||
|
NetworkManager {
|
||||||
|
bind,
|
||||||
|
clients: HashMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn listen_websocket(bind: String, manager: Addr<NetworkManager>) {
|
||||||
|
let try_socket = TcpListener::bind(&bind).await;
|
||||||
|
let mut listener = try_socket.expect("Failed to bind");
|
||||||
|
info!("Listening on: {}", bind);
|
||||||
|
|
||||||
|
while let Ok((stream, _)) = listener.accept().await {
|
||||||
|
let addr = stream
|
||||||
|
.peer_addr()
|
||||||
|
.expect("connected streams should have a peer address");
|
||||||
|
info!("Peer address: {}", addr);
|
||||||
|
|
||||||
|
let stream = tokio_tungstenite::accept_async(stream)
|
||||||
|
.await
|
||||||
|
.expect("Error during the websocket handshake occurred");
|
||||||
|
info!("New WebSocket connection: {}", addr);
|
||||||
|
|
||||||
|
NetworkConnection::create(|_ctx| NetworkConnection {
|
||||||
|
conn_id: 0,
|
||||||
|
connected: false,
|
||||||
|
stream,
|
||||||
|
manager: manager.clone(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue