Skip to content

Commit e8e9dc7

Browse files
committed
feat: heartbeat
1 parent 5479b91 commit e8e9dc7

5 files changed

Lines changed: 41 additions & 4 deletions

File tree

‎player/src/connection.rs‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,8 @@ impl ConnectionActor {
235235
}
236236

237237
async fn run(&mut self) {
238+
let mut heartbeat_interval = tokio::time::interval(tokio::time::Duration::from_secs(60));
239+
238240
loop {
239241
tokio::select! {
240242
// received a command with a message to send to the server
@@ -323,6 +325,11 @@ impl ConnectionActor {
323325
}
324326
}
325327
},
328+
329+
// time to send a heartbeat
330+
_ = heartbeat_interval.tick() => {
331+
self.stream.send(&Message::Heartbeat).await.unwrap();
332+
},
326333
}
327334
}
328335

@@ -399,6 +406,7 @@ impl ConnectionActor {
399406
Message::RefreshRoomList => println!("unexpected message: {:?}", message),
400407
Message::Text(_) => println!("unexpected message: {:?}", message),
401408
Message::Request { .. } => println!("unexpected message: {:?}", message),
409+
Message::Heartbeat => println!("unexpected message: {:?}", message),
402410
}
403411
}
404412

‎player/src/main.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ async fn main() -> std::io::Result<()> {
3737
let args: Vec<String> = std::env::args().collect();
3838
let is_temp = match args.get(1).map(|s| s.as_str()) {
3939
Some("-t") => true, // use temporary identity for testing
40-
_ => false, // len is 1 but index is 1 :3
40+
_ => false, // len is 1 but index is 1 :3
4141
};
4242

4343
let mut t = MainThread::setup(is_temp).await;

‎protocol/src/lib.rs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ pub enum Message {
6262
AudioData(AudioData),
6363
Text(String),
6464

65+
Heartbeat,
66+
6567
Notification(Notification),
6668

6769
Request { request_id: u32, data: Request },

‎server/Cargo.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ edition.workspace = true
88
bincode = "1.3.3"
99
futures = "0.3.28"
1010
protocol = { path = "../protocol" }
11-
tokio = { version = "1.28.1", features = ["macros", "net", "rt-multi-thread", "io-util", "sync"] }
11+
tokio = { version = "1.28.1", features = ["macros", "net", "rt-multi-thread", "io-util", "sync", "time"] }

‎server/src/main.rs‎

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::collections::{HashMap, VecDeque};
22
use std::error::Error;
33
use std::net::SocketAddr;
44
use std::sync::Arc;
5+
use std::time::{Duration, Instant};
56

67
use futures::StreamExt;
78
use tokio::io;
@@ -163,6 +164,7 @@ struct PeerHandle {
163164
struct Peer {
164165
id: String,
165166
room_id: Option<u32>,
167+
last_heartbeat: Instant,
166168
addr: SocketAddr,
167169
stream: FrameStream,
168170
rx: Rx, // mpsc channel used to receive messages from peers
@@ -189,6 +191,7 @@ impl Peer {
189191
Ok(Peer {
190192
id,
191193
room_id: None,
194+
last_heartbeat: Instant::now(),
192195
addr,
193196
stream,
194197
rx,
@@ -277,10 +280,19 @@ async fn handle_handshaken_connection(
277280
return handle_authenticated_connection(state, stream, id, name).await;
278281
}
279282

280-
_ => return Err("not allowed".into()),
283+
_ => {
284+
println!("not allowed request was {:?}", request);
285+
return Err("not allowed".into());
286+
}
281287
},
282288

283-
_ => return Err("not allowed".into()),
289+
// sure
290+
Message::Heartbeat => {}
291+
292+
_ => {
293+
println!("not allowed message was {:?}", msg);
294+
return Err("not allowed".into());
295+
}
284296
}
285297
}
286298

@@ -362,6 +374,8 @@ async fn handle_authenticated_connection(
362374
// create a new Peer
363375
let mut peer = Peer::new(state.clone(), stream, id, name).await?;
364376

377+
let mut heartbeat_check_interval = tokio::time::interval(tokio::time::Duration::from_secs(10));
378+
365379
// process incoming messages until disconnected
366380
loop {
367381
tokio::select! {
@@ -387,6 +401,14 @@ async fn handle_authenticated_connection(
387401
// socket disconnected
388402
None => break
389403
},
404+
405+
// if we haven't received a heartbeat in the last 2 minutes, disconnect them
406+
_ = heartbeat_check_interval.tick() => {
407+
let elapsed = peer.last_heartbeat.elapsed();
408+
if elapsed > Duration::from_secs(120) {
409+
break
410+
}
411+
}
390412
}
391413
}
392414

@@ -487,6 +509,11 @@ async fn handle_message(
487509
Ok(())
488510
}
489511

512+
Message::Heartbeat => {
513+
peer.last_heartbeat = Instant::now();
514+
Ok(())
515+
}
516+
490517
// should not be reached
491518
Message::QueryRoomList => Ok(()),
492519
Message::Notification(_) => Ok(()),

0 commit comments

Comments
 (0)