Skip to content

Commit c860682

Browse files
committed
refactor: server...
1 parent ba117eb commit c860682

10 files changed

Lines changed: 1052 additions & 705 deletions

File tree

‎Cargo.lock‎

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎player/src/connection.rs‎

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,6 @@ impl ConnectionActorHandle {
6262
Ok(())
6363
}
6464

65-
pub fn refresh_room_list(&mut self) -> Result<(), Box<dyn Error>> {
66-
self.send(Message::RefreshRoomList)
67-
}
68-
6965
// keep this one private for sure though
7066
async fn send_request(&self, data: Request) -> Result<Response, Box<dyn Error>> {
7167
let (send, recv) = oneshot::channel::<Response>();
@@ -365,7 +361,6 @@ impl ConnectionActor {
365361

366362
// should not be receiving these
367363
Message::QueryRoomList => println!("unexpected message: {:?}", message),
368-
Message::RefreshRoomList => println!("unexpected message: {:?}", message),
369364
Message::Text(_) => println!("unexpected message: {:?}", message),
370365
Message::Request { .. } => println!("unexpected message: {:?}", message),
371366
Message::Heartbeat => println!("unexpected message: {:?}", message),

‎player/src/preferences.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ fn generate_id() -> String {
4040
fn default_servers() -> Vec<Server> {
4141
vec![Server {
4242
name: "local".into(),
43-
addr: "127.0.0.1:8080".into(),
43+
addr: "127.0.0.1:5119".into(),
4444
}]
4545
}
4646

‎protocol/src/lib.rs‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ pub struct RoomOptions {
6565
pub enum Message {
6666
QueryRoomList,
6767

68-
RefreshRoomList,
6968
AudioData(AudioData),
7069
Text(String),
7170

‎protocol/src/network.rs‎

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::sync::Arc;
2+
13
use bytes::{Bytes, BytesMut};
24
use thiserror::Error;
35
use tokio::io::{AsyncRead, AsyncWrite};
@@ -17,6 +19,7 @@ pub fn message_stream<S: AsyncRead + AsyncWrite>(stream: S) -> MessageStream<S>
1719
Framed::new(stream, MessageCodec::new())
1820
}
1921

22+
#[derive(Debug)]
2023
pub struct MessageCodec {
2124
inner: LengthDelimitedCodec,
2225
}
@@ -55,11 +58,23 @@ impl Encoder<&Message> for MessageCodec {
5558
}
5659
}
5760

58-
#[derive(Debug, Error)]
61+
#[derive(Debug, Error, Clone)]
5962
pub enum MessageStreamError {
6063
#[error(transparent)]
61-
Bincode(#[from] bincode::Error),
64+
Bincode(#[from] Arc<bincode::Error>),
6265

6366
#[error(transparent)]
64-
Io(#[from] std::io::Error),
67+
Io(#[from] Arc<std::io::Error>),
68+
}
69+
70+
impl From<bincode::Error> for MessageStreamError {
71+
fn from(value: bincode::Error) -> Self {
72+
Self::Bincode(Arc::new(value))
73+
}
74+
}
75+
76+
impl From<std::io::Error> for MessageStreamError {
77+
fn from(value: std::io::Error) -> Self {
78+
Self::Io(Arc::new(value))
79+
}
6580
}

‎server/Cargo.toml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ version.workspace = true
55
edition.workspace = true
66

77
[dependencies]
8+
async-trait = "0.1.73"
89
bincode = "1.3.3"
910
futures = "0.3.28"
1011
protocol = { path = "../protocol" }

‎server/src/connection.rs‎

Lines changed: 285 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,285 @@
1+
use std::collections::HashMap;
2+
use std::error::Error;
3+
use std::hash::Hash;
4+
use std::net::SocketAddr;
5+
use std::task::Poll;
6+
use std::time::Instant;
7+
8+
use async_trait::async_trait;
9+
use futures::future::{join_all, poll_fn};
10+
use futures::task::AtomicWaker;
11+
use futures::{SinkExt, StreamExt};
12+
use tokio::net::TcpStream;
13+
14+
use protocol::network::{message_stream, MessageStream, MessageStreamError};
15+
use protocol::{Message, Notification};
16+
17+
use crate::Id;
18+
19+
#[async_trait]
20+
pub trait Connections {
21+
type Key: Hash + PartialEq + Eq + Clone + Send + Sync;
22+
type Conn: Connection + Send + Sync;
23+
24+
fn new() -> Self
25+
where
26+
Self: Sized;
27+
28+
fn get_inner(&self) -> &HashMap<Self::Key, Self::Conn>;
29+
fn get_inner_mut(&mut self) -> &mut HashMap<Self::Key, Self::Conn>;
30+
fn get_waker(&self) -> &AtomicWaker;
31+
32+
fn remove(&mut self, k: &Self::Key) -> Option<Self::Conn>;
33+
34+
fn get(&self, k: &Self::Key) -> Option<&Self::Conn> {
35+
self.get_inner().get(k)
36+
}
37+
fn get_mut(&mut self, k: &Self::Key) -> Option<&mut Self::Conn> {
38+
self.get_inner_mut().get_mut(k)
39+
}
40+
41+
async fn broadcast(&mut self, message: &Message) {
42+
let futs = self
43+
.get_inner_mut()
44+
.values_mut()
45+
// do some error handling (this comment is so the formatter does it how i want)
46+
.map(|c| c.send(message));
47+
join_all(futs).await;
48+
}
49+
async fn broadcast_others(&mut self, exclude_id: &Self::Key, message: &Message) {
50+
let futs = self
51+
.get_inner_mut()
52+
.iter_mut()
53+
.filter(|(id, _)| *id != exclude_id)
54+
.map(|(_, c)| c.send(message));
55+
join_all(futs).await;
56+
}
57+
async fn send_to(&mut self, key: Self::Key, message: &Message) {
58+
if let Some(c) = self.get_inner_mut().get_mut(&key) {
59+
c.send(message).await;
60+
}
61+
}
62+
63+
/// Polls all clients' streams for the next message/error/disconnect.
64+
/// Returns the first thing received and the id of the client who created it.
65+
async fn next_message(&mut self) -> (Self::Key, Option<Result<Message, MessageStreamError>>) {
66+
poll_fn(|cx| {
67+
// wake up this task when we add/remove clients
68+
self.get_waker().register(cx.waker());
69+
70+
// if any streams are ready, return their value
71+
for (id, client) in self.get_inner_mut().iter_mut() {
72+
match client.get_mut().poll_next_unpin(cx) {
73+
// TODO: fix this clone maybe
74+
Poll::Ready(message) => {
75+
return Poll::Ready((id.clone(), message));
76+
}
77+
Poll::Pending => continue,
78+
}
79+
}
80+
81+
// no streams had anything, return Pending
82+
// stream.poll_next_unpin will register the context for wakeup for us
83+
Poll::Pending
84+
})
85+
.await
86+
}
87+
}
88+
89+
#[derive(Debug)]
90+
pub struct UnauthedConnections {
91+
next_id: usize,
92+
93+
inner: HashMap<usize, UnauthedConnection>,
94+
waker: AtomicWaker,
95+
}
96+
97+
impl Connections for UnauthedConnections {
98+
type Key = usize;
99+
type Conn = UnauthedConnection;
100+
101+
fn new() -> Self {
102+
Self {
103+
next_id: 0,
104+
inner: HashMap::new(),
105+
waker: AtomicWaker::new(),
106+
}
107+
}
108+
fn get_inner(&self) -> &HashMap<Self::Key, Self::Conn> {
109+
&self.inner
110+
}
111+
fn get_inner_mut(&mut self) -> &mut HashMap<Self::Key, Self::Conn> {
112+
&mut self.inner
113+
}
114+
fn get_waker(&self) -> &AtomicWaker {
115+
&self.waker
116+
}
117+
fn remove(&mut self, key: &Self::Key) -> Option<Self::Conn> {
118+
self.inner.remove(key)
119+
}
120+
}
121+
122+
impl UnauthedConnections {
123+
pub fn insert(&mut self, conn: UnauthedConnection) {
124+
let id = self.next_id;
125+
self.next_id += 1;
126+
self.get_inner_mut().insert(id, conn);
127+
}
128+
}
129+
130+
#[derive(Debug)]
131+
pub struct Clients {
132+
inner: HashMap<Id, Client>,
133+
waker: AtomicWaker,
134+
}
135+
136+
impl Connections for Clients {
137+
type Key = Id;
138+
type Conn = Client;
139+
140+
fn new() -> Self {
141+
Self {
142+
inner: HashMap::new(),
143+
waker: AtomicWaker::new(),
144+
}
145+
}
146+
fn get_inner(&self) -> &HashMap<Self::Key, Self::Conn> {
147+
&self.inner
148+
}
149+
fn get_inner_mut(&mut self) -> &mut HashMap<Self::Key, Self::Conn> {
150+
&mut self.inner
151+
}
152+
fn get_waker(&self) -> &AtomicWaker {
153+
&self.waker
154+
}
155+
fn remove(&mut self, key: &Id) -> Option<Client> {
156+
self.waker.wake();
157+
self.inner.remove(key)
158+
}
159+
}
160+
161+
impl Clients {
162+
pub fn insert(&mut self, client: Client) {
163+
self.inner.insert(client.id.clone(), client);
164+
165+
// wake our poll method
166+
self.waker.wake();
167+
}
168+
169+
pub fn names(&self) -> HashMap<Id, String> {
170+
self.inner
171+
.iter()
172+
.map(|(key, client)| (key.clone(), client.name.clone()))
173+
.collect()
174+
}
175+
}
176+
177+
#[async_trait]
178+
pub trait Connection {
179+
fn get_ref(&self) -> &MessageStream<TcpStream>;
180+
fn get_mut(&mut self) -> &mut MessageStream<TcpStream>;
181+
182+
fn log(&self, s: String);
183+
fn log_error(&self, e: impl Error);
184+
fn log_error_boxed(&self, e: Box<dyn Error>);
185+
186+
async fn send(&mut self, message: &Message) {
187+
let inner = self.get_mut();
188+
if let Err(e) = inner.send(message).await {
189+
self.log_error(e);
190+
}
191+
}
192+
async fn notify(&mut self, notification: Notification) {
193+
self.send(&Message::Notification(notification)).await
194+
}
195+
}
196+
197+
#[derive(Debug)]
198+
pub struct UnauthedConnection {
199+
stream: MessageStream<TcpStream>,
200+
addr: SocketAddr,
201+
}
202+
203+
impl Connection for UnauthedConnection {
204+
fn get_ref(&self) -> &MessageStream<TcpStream> {
205+
&self.stream
206+
}
207+
fn get_mut(&mut self) -> &mut MessageStream<TcpStream> {
208+
&mut self.stream
209+
}
210+
211+
fn log(&self, s: String) {
212+
println!("* {} - {}", self.addr, s);
213+
}
214+
fn log_error(&self, e: impl Error) {
215+
eprintln!("* {} - err: {}", self.addr, e);
216+
}
217+
fn log_error_boxed(&self, e: Box<dyn Error>) {
218+
eprintln!("* {} - err: {}", self.addr, e);
219+
}
220+
}
221+
222+
impl UnauthedConnection {
223+
pub fn from_tcp(stream: TcpStream, addr: SocketAddr) -> Self {
224+
Self {
225+
stream: message_stream(stream),
226+
addr,
227+
}
228+
}
229+
230+
pub fn authenticate(self, id: Id, name: String) -> Client {
231+
Client {
232+
stream: self.stream,
233+
id,
234+
name,
235+
last_heartbeat: Instant::now(),
236+
}
237+
}
238+
}
239+
240+
#[derive(Debug)]
241+
pub struct Client {
242+
stream: MessageStream<TcpStream>,
243+
pub id: String,
244+
name: String,
245+
last_heartbeat: Instant,
246+
}
247+
248+
impl Connection for Client {
249+
fn get_ref(&self) -> &MessageStream<TcpStream> {
250+
&self.stream
251+
}
252+
fn get_mut(&mut self) -> &mut MessageStream<TcpStream> {
253+
&mut self.stream
254+
}
255+
256+
fn log(&self, s: String) {
257+
println!("* client {} - {}", self.id, s);
258+
}
259+
fn log_error(&self, e: impl Error) {
260+
eprintln!("* client {} - err: {}", self.id, e);
261+
}
262+
fn log_error_boxed(&self, e: Box<dyn Error>) {
263+
eprintln!("* client {} - err: {}", self.id, e);
264+
}
265+
}
266+
267+
impl Client {
268+
pub fn set_heartbeat(&mut self) {
269+
self.last_heartbeat = Instant::now();
270+
}
271+
272+
// TODO
273+
// pub async fn run(&mut self, state: Arc<Mutex<Shared>>) {
274+
// let mut heartbeat_check_interval = tokio::time::interval(Duration::from_secs(10));
275+
// // if we haven't received a heartbeat in the last 2 minutes, disconnect them
276+
// _ = heartbeat_check_interval.tick() => {
277+
// let elapsed = self.last_heartbeat.elapsed();
278+
// if elapsed > Duration::from_secs(120) {
279+
// break
280+
// }
281+
// }
282+
// }
283+
// }
284+
// }
285+
}

0 commit comments

Comments
 (0)