use std::{ net::TcpStream, sync::{Arc, Mutex}, }; use crate::networking::websocket::{PacketMessageConvert, Websocket}; use bevy_ecs::system::Resource; use crossbeam::channel::{unbounded, Receiver, Sender}; use starkingdoms_common::packet::{MsgFromError, Packet, SpecialDisconnectPacket}; use tungstenite::{connect, stream::MaybeTlsStream, Message, WebSocket}; impl PacketMessageConvert for Packet { type M = Message; fn from_message(value: &Message) -> Result { match value { Message::Text(s) => serde_json::from_str(s).map_err(MsgFromError::JSONError), Message::Binary(b) => serde_json::from_slice(b).map_err(MsgFromError::JSONError), Message::Close(_) => Ok(Packet::_SpecialDisconnect(SpecialDisconnectPacket {})), Message::Frame(_) | Message::Pong(_) | Message::Ping(_) => { Err(MsgFromError::InvalidMessageType) } } } fn as_message(&self) -> Message { Message::Text( serde_json::to_string(self) .expect("failed to serialize packet to json") .into(), ) } } #[derive(Resource, Debug)] pub struct Ws { socket: Arc>>>, pub sender: Sender, pub receiver: Receiver, packet_receiver: Receiver, } impl Websocket for Ws { fn new() -> Self { let (socket, _) = connect("ws://localhost:3000").expect("Failed to connect to server"); let socket = Arc::new(Mutex::new(socket)); let (packet_sender, receiver) = unbounded(); let (sender, packet_receiver) = unbounded(); let socket_clone = socket.clone(); std::thread::spawn(move || { let socket = socket_clone; loop { let message = socket .lock() .unwrap() .read() .expect("Failed to reading message"); let packet = Packet::from_message(&message).expect("Server sent invalid packet"); packet_sender .send(packet) .expect("Couldn't send packet to server"); } }); Ws { socket, sender, receiver, packet_receiver, } } fn send_packet(&mut self, packet: Packet) { self.socket .lock() .unwrap() .send(packet.as_message()) .expect("Couldn't send packet to server"); } }