42bcebb50c
Focusing mostly on getting main in shape and figuring out how to make the connections flow. The main is pretty much there, going to be a bit more when I take a shot at federation.
92 lines
2.9 KiB
Rust
92 lines
2.9 KiB
Rust
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<RwLock<State>>,
|
|
// 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<TaggedClientMessage>,
|
|
// This probably could be a more specific type
|
|
// But we should be filtering and sending back only stuff that matters
|
|
message_recv: broadcast::Receiver<TaggedClientMessage>,
|
|
// 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<MessageId>,
|
|
db_handle: Pool<AsyncPgConnection>,
|
|
// Filled once user is authed
|
|
username: Option<String>,
|
|
// how do I keep track of activity??? maybe there's a hashmap that gets updated
|
|
subscriptions: HashSet<MessageId>,
|
|
|
|
quic_connection: quinn::Connection,
|
|
close_handle: broadcast::Receiver<()>
|
|
}
|
|
impl Client {
|
|
pub fn new(
|
|
statehandle: Arc<RwLock<State>>,
|
|
(message_send,message_recv): (
|
|
broadcast::Sender<TaggedClientMessage>,
|
|
broadcast::Receiver<TaggedClientMessage>),
|
|
message_ack: mpsc::Sender<MessageId>,
|
|
db_handle: Pool<AsyncPgConnection>,
|
|
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<u8> = 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
|
|
|
|
}
|
|
}
|