99 lines
2.5 KiB
Rust
99 lines
2.5 KiB
Rust
use std::{net::SocketAddr, time::Instant};
|
|
|
|
use crate::Sender;
|
|
|
|
use super::socket::{Socket, SocketContent, SocketCreateInfo};
|
|
|
|
use anyhow::Result;
|
|
|
|
pub struct Client {
|
|
socket: Socket,
|
|
|
|
server: SocketAddr,
|
|
last_message: Option<Instant>,
|
|
}
|
|
|
|
impl Client {
|
|
pub fn new(create_info: SocketCreateInfo, server: impl Into<SocketAddr>) -> Result<Self> {
|
|
Ok(Self {
|
|
socket: Socket::new(create_info)?,
|
|
|
|
server: server.into(),
|
|
last_message: None,
|
|
})
|
|
}
|
|
|
|
pub fn server_address(&self) -> SocketAddr {
|
|
self.server
|
|
}
|
|
|
|
pub fn check_heartbeat(&mut self) -> Result<()> {
|
|
let now = Instant::now();
|
|
|
|
if (now - self.socket.start) > self.socket.heartbeat_interval {
|
|
self.socket.start += self.socket.heartbeat_interval;
|
|
|
|
Client::send(self, "")?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub fn send(&self, msg: &str) -> Result<()> {
|
|
self.socket.send(self.server, msg)
|
|
}
|
|
|
|
pub fn receive(&mut self) -> Result<Vec<SocketContent>> {
|
|
let now = Instant::now();
|
|
let mut content = Vec::new();
|
|
|
|
while let Some((addr, msg)) = match self.socket.receive() {
|
|
Ok(r) => r,
|
|
Err(err) => {
|
|
// if content is empty return the error
|
|
// if not, ignore the error and break the loop
|
|
if content.is_empty() {
|
|
return Err(err);
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
} {
|
|
if addr != self.server {
|
|
// discard message if thats from another source
|
|
continue;
|
|
}
|
|
|
|
match &mut self.last_message {
|
|
Some(last_message) => *last_message = now,
|
|
None => {
|
|
self.last_message = Some(now);
|
|
content.push(SocketContent::NewConnection(addr));
|
|
}
|
|
}
|
|
|
|
if !msg.is_empty() {
|
|
content.push(SocketContent::Message(addr, msg));
|
|
}
|
|
}
|
|
|
|
if let Some(last_message) = self.last_message {
|
|
if (now - last_message) > self.socket.connection_time_out() {
|
|
self.last_message = None;
|
|
content.push(SocketContent::TimeOut(self.server));
|
|
}
|
|
}
|
|
|
|
Ok(content)
|
|
}
|
|
}
|
|
|
|
impl Sender for Client {
|
|
fn send(&mut self, _: SocketAddr, msg: &str) -> Result<()> {
|
|
Client::send(self, msg)
|
|
}
|
|
|
|
fn is_server(&self) -> bool {
|
|
false
|
|
}
|
|
}
|