Handle connection event properly

This commit is contained in:
Hamcha 2020-10-05 02:24:23 +02:00
parent f7255b3617
commit b615c86820
Signed by: hamcha
GPG Key ID: 41467804B19A3315
10 changed files with 82 additions and 30 deletions

9
src/components/map.rs Normal file
View File

@ -0,0 +1,9 @@
pub struct Tile {
contents: Vec<u32>,
}
pub struct Map {
width: u16,
height: u16,
tiles: Vec<Tile>,
}

View File

@ -1,3 +1,3 @@
pub mod network;
pub mod map;
pub mod transform;
pub mod viewport;

View File

@ -1,4 +0,0 @@
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct NetworkConnection {
conn_id: u64,
}

View File

@ -1,6 +1,5 @@
use ultraviolet::Vec2;
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Transform {
pub chunk_id: (u16, u16),
pub position: Vec2,

View File

@ -1,6 +1,5 @@
use ultraviolet::Vec2;
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Viewport {
pub chunk_id: (u16, u16),
pub position: Vec2,

View File

@ -1,4 +1,6 @@
use crate::network::NetworkMessage;
use crate::network::{NetworkMessage, NetworkPayload};
use async_std::sync::Arc;
use async_std::sync::RwLock;
use async_std::sync::{Receiver, Sender};
use shipyard::{error, World};
use std::collections::HashMap;
@ -16,7 +18,12 @@ impl Game {
// Create world
let world = World::default();
// Create workload
// Create init workload
world.run(|| {
//todo
});
// Create update workload
world.add_workload("update").build();
Game {
@ -30,15 +37,29 @@ impl Game {
self.world.try_run_workload("update")
}
pub async fn read_loop(&self, net_in: Receiver<NetworkMessage>) {
pub async fn read_loop(game: Arc<RwLock<Self>>, net_in: Receiver<NetworkMessage>) {
loop {
let message = net_in.recv().await.expect("could not read from channel");
self.net_out
.send(NetworkMessage {
conn_id: message.conn_id,
data: tungstenite::Message::text("hello"),
})
.await;
match message.data {
NetworkPayload::Connected => {
log::info!("[{:?}] connected", &message.conn_id);
game.write()
.await
.players
.insert(message.conn_id, Player {});
}
NetworkPayload::Message(msg) => {
log::info!("[{:?}] said {:?}", &message.conn_id, msg);
game.write()
.await
.net_out
.send(NetworkMessage {
conn_id: message.conn_id,
data: NetworkPayload::Message(tungstenite::Message::text("hello")),
})
.await;
}
}
}
}
}

View File

@ -8,6 +8,7 @@ use crate::config::Settings;
use crate::game::Game;
use crate::network::listen;
use async_std::sync::Arc;
use async_std::sync::RwLock;
use async_std::{sync::channel, task};
use env_logger::Env;
use std::time::Duration;
@ -24,17 +25,15 @@ async fn run() {
let (in_s, in_r) = channel(10);
let (out_s, out_r) = channel(10);
let game = Arc::new(Game::new(out_s));
let game = Arc::new(RwLock::new(Game::new(out_s)));
let game_read_loop = game.clone();
task::spawn(async move {
game_read_loop.read_loop(in_r).await;
});
task::spawn(Game::read_loop(game_read_loop, in_r));
task::spawn(async move {
loop {
let game = game.clone();
task::spawn(async move { game.update().expect("update failed") });
task::spawn(async move { game.read().await.update().expect("update failed") });
task::sleep(Duration::from_millis(MIN_UPDATE_MS)).await;
}
});

View File

@ -11,11 +11,18 @@ use futures_util::{stream::SplitSink, stream::SplitStream, SinkExt, StreamExt};
#[derive(Debug)]
pub struct NetworkMessage {
pub conn_id: usize,
pub data: tungstenite::Message,
pub data: NetworkPayload,
}
#[derive(Debug)]
pub enum NetworkPayload {
Connected,
Message(tungstenite::Message),
}
struct Connection {
stream: SplitSink<WebSocketStream<TcpStream>, tungstenite::Message>,
address: SocketAddr,
conn_id: usize,
}
@ -39,10 +46,14 @@ impl NetworkManager {
.connections
.get_mut(&message.conn_id)
.expect("cant send message to an unregistered connection");
conn.stream
.send(message.data)
.await
.expect("could not send message to connection");
match message.data {
NetworkPayload::Message(msg) => conn
.stream
.send(msg)
.await
.expect("could not send message to connection"),
_ => (),
}
}
}
@ -70,13 +81,27 @@ async fn accept_connection(
stream: TcpStream,
incoming: Sender<NetworkMessage>,
) -> Connection {
// Generate random connection id
let conn_id = rand::random();
// Get streams
let ws_stream = accept_async(stream).await.expect("could not accept");
log::info!("New WebSocket connection: {}", peer);
let (ws_sender, ws_receiver) = ws_stream.split();
// Send event to game instance
incoming
.send(NetworkMessage {
conn_id,
data: NetworkPayload::Connected,
})
.await;
// Start read loop
task::spawn(read_loop(ws_receiver, incoming, conn_id));
// Return connection instance for network manager
Connection {
stream: ws_sender,
address: peer,
conn_id,
}
}
@ -87,12 +112,16 @@ async fn read_loop(
conn_id: usize,
) {
loop {
let data = stream
let message = stream
.next()
.await
.expect("failed getting the next message")
.expect("received error while reading");
ch.send(NetworkMessage { conn_id, data }).await;
ch.send(NetworkMessage {
conn_id,
data: NetworkPayload::Message(message),
})
.await;
}
}

View File

View File

@ -1 +1 @@
pub mod client;