use fedichat::RoomId; use fedichat::client::TaggedClientMessage; use fedichat::state::StatePath; use diesel_async::AsyncPgConnection; use diesel_async::pooled_connection::deadpool::Pool; use tokio::sync::{broadcast,mpsc,RwLock}; use tokio::select; use std::collections::HashSet; use std::sync::{Arc}; use quinn::{SendStream,RecvStream}; use crate::state::State; pub enum MessageId { State(RoomId,StatePath), Messages(RoomId) } pub struct Client { statehandle: Arc>, // Channel for local messages, all are broadcast to all // Every client gets to filter based on name // Same with state changes // Potentially could be turned into a more efficient localised filter maybe // Remote messages can come through the same channel maybe? message_send: broadcast::Sender, // This probably could be a more specific type // But we should be filtering and sending back only stuff that matters message_recv: broadcast::Receiver, // Sends back match if anything filtered matched the client filters // Connections are closed after a period of inactivity so this should be fine, // if client is connected acks are sent, if inactive connection is closed message_ack: mpsc::Sender, db_handle: Pool, // Filled once user is authed username: Option, // how do I keep track of activity??? maybe there's a hashmap that gets updated subscriptions: HashSet, quic_connection: quinn::Connection, close_handle: broadcast::Receiver<()> } impl Client { pub fn new( statehandle: Arc>, (message_send,message_recv): ( broadcast::Sender, broadcast::Receiver), message_ack: mpsc::Sender, db_handle: Pool, quic_connection: quinn::Connection, close_handle: broadcast::Receiver<()> ) -> Self { Client { statehandle, message_send, message_recv, message_ack, db_handle, username: None, subscriptions: HashSet::new(), quic_connection, close_handle } } pub async fn run(mut self) { let mut chunk_arr = [0u8; 1024]; let mut serde_buf: Vec = Vec::new(); loop { select!{ //result = self.quic_recv.read(&mut chunk_arr) => { // unimplemented!() //} result = self.message_recv.recv() => { unimplemented!() } _result = self.close_handle.recv() => { // Maybe TODO do I need to check the result? break; } } } // Do any cleanup that needs done } }