-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathconnection.rs
More file actions
65 lines (53 loc) · 1.95 KB
/
connection.rs
File metadata and controls
65 lines (53 loc) · 1.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
use crate::group_table::GroupTable;
use async_chat::utils::{self};
use async_chat::{FromClient, FromServer};
use async_std::io::BufReader;
use async_std::net::TcpStream;
use async_std::prelude::*;
use async_std::sync::{Arc, Mutex};
use anyhow::{bail, Result};
/// Wraps a TCP connection to a client, allowing safe async writes.
pub struct Outbound(Mutex<TcpStream>);
use async_std::sync::Arc;
use async_std::sync::Mutex;
pub struct Outbound(Mutex<TcpStream>);
impl Outbound {
pub fn new(to_client: TcpStream) -> Self {
Self(Mutex::new(to_client))
}
pub async fn send(&self, packet: FromServer) -> Result<()> {
let mut guard = self.0.lock().await;
utils::send_as_json(&mut *guard, &packet).await?;
guard.flush().await?;
Ok(())
}
}
/// Handles a new client connection, listens for messages, and interacts with group logic.
pub async fn serve(socket: TcpStream, groups: Arc<GroupTable>) -> Result<()> {
let outbound = Arc::new(Outbound::new(socket.clone()));
let buffered = BufReader::new(socket);
let mut from_client = utils::receive_as_json(buffered);
while let Some(request_result) = from_client.next().await {
let request = request_result?;
let result: Result<()> = match request {
FromClient::Join { group_name } => {
let group = groups.get_or_create(group_name);
group.join(outbound.clone());
Ok(())
}
FromClient::Post { group_name, message } => match groups.get(&group_name) {
Some(group) => {
group.post(message);
Ok(())
}
None => bail!("Group '{}' does not exist", group_name),
},
};
if let Err(message) = result {
let report = FromServer::Error(message.to_string());
outbound.send(report).await?;
}
}
println!("Client disconnected.");
Ok(())
}