From f92e9f6f07b1e3834c2ca58ce3510734819d08e4 Mon Sep 17 00:00:00 2001 From: Arne Dußin Date: Wed, 27 Jan 2021 14:01:50 +0100 Subject: Rework graf karto to fit the client/server structure --- src/net/server/connection.rs | 84 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 src/net/server/connection.rs (limited to 'src/net/server/connection.rs') diff --git a/src/net/server/connection.rs b/src/net/server/connection.rs new file mode 100644 index 0000000..801eb4b --- /dev/null +++ b/src/net/server/connection.rs @@ -0,0 +1,84 @@ +//! A TCP-connection from a client to the server. + +use super::super::packet::{Packet, PacketRwError}; +use super::connection_manager::ConnId; +use serde::de::DeserializeOwned; +use serde::Serialize; +use std::fmt::Debug; +use std::net::TcpStream; +use std::sync::mpsc::Sender; +use std::thread::{self, JoinHandle}; + +/// Holds a stream to the client and manages receiving packets from said client +/// in an extra thread. +pub struct Connection { + stream: TcpStream, + rcv_thread_handle: JoinHandle<()>, +} + +impl Connection { + /// Start up the receiving thread after a client connection has been detected. + /// Will create a ghost disconnect packet in case the client disconnects. + pub(super) fn start_rcv
( + conn_id: ConnId, + stream: TcpStream, + packet_tx: Sender<(ConnId, Packet
)>, + ) -> Self + where + P: 'static + Debug + Send + DeserializeOwned + Serialize, + { + let mut stream_cl = stream + .try_clone() + .expect("Unable to clone TcpStream handle"); + let rcv_thread_handle = thread::spawn(move || { + let mut running = true; + while running { + // Read the newest packet from the stream. + let packet = match Packet::read_from_stream(&mut stream_cl) { + Ok(packet) => dbg!(packet), + Err(PacketRwError::Closed) => { + // Stop the thread after this packet. + running = false; + + /* Generate an internal disconnection packet, so the connection + * manager can call cleanup code if necessary. + */ + Packet::Disconnect + } + Err(err) => { + error!( + "Receiving packet failed. Connection `{}`. {:?}", + conn_id, err + ); + + // Ignore the received data. + continue; + } + }; + + /* Try sending the packet to the Connection manager. If it has already + * stopped and hung up on the channel, stop this receive thread as well. + */ + if packet_tx.send((conn_id, packet)).is_err() { + info!("Shutting down connection `{}`", conn_id); + running = false; + } + } + + info!("Packet receive thread has stopped running."); + }); + + Self { + stream, + rcv_thread_handle, + } + } + + /// Send a packet to the client via TCP. + pub(super) fn send
(&mut self, packet: &Packet
) -> Result<(), PacketRwError> + where + P: 'static + Debug + Send + DeserializeOwned + Serialize, + { + packet.write_to_stream(&mut self.stream) + } +} -- cgit v1.2.3-70-g09d2