Implement remaining parts
This commit is contained in:
parent
b06da9472e
commit
a3d61f46c3
1 changed files with 34 additions and 26 deletions
|
|
@ -1,23 +1,22 @@
|
||||||
|
// TODO Logging
|
||||||
|
|
||||||
mod conn;
|
mod conn;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
use std::any;
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
use std::time::Duration;
|
||||||
|
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use conn::{ConnMaintenance, ConnRx, ConnTx};
|
use conn::{ConnMaintenance, ConnRx, ConnTx};
|
||||||
use cove_core::packets::{
|
use cove_core::packets::{
|
||||||
Cmd, HelloCmd, HelloRpl, JoinNtf, NickCmd, NickNtf, NickRpl, Ntf, Packet, PartNtf, SendCmd,
|
Cmd, HelloCmd, HelloRpl, JoinNtf, NickCmd, NickNtf, NickRpl, Packet, PartNtf, SendCmd, SendNtf,
|
||||||
SendNtf, SendRpl, WhoCmd,
|
SendRpl, WhoCmd, WhoRpl,
|
||||||
};
|
};
|
||||||
use cove_core::{Identity, Message, MessageId, Session, SessionId};
|
use cove_core::{Identity, Message, MessageId, Session, SessionId};
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use tokio::net::{TcpListener, TcpStream};
|
use tokio::net::{TcpListener, TcpStream};
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
use tokio_tungstenite::tungstenite::http::header::LAST_MODIFIED;
|
|
||||||
use util::timestamp;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct Client {
|
struct Client {
|
||||||
|
|
@ -63,6 +62,20 @@ impl Room {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn join(&mut self, client: Client) {
|
||||||
|
if self.clients.contains_key(&client.session.id) {
|
||||||
|
// Session ids are generated randomly and a collision should be very
|
||||||
|
// unlikely.
|
||||||
|
panic!("duplicated session id");
|
||||||
|
}
|
||||||
|
|
||||||
|
self.notify_all(&Packet::ntf(JoinNtf {
|
||||||
|
who: client.session.clone(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
self.clients.insert(client.session.id, client);
|
||||||
|
}
|
||||||
|
|
||||||
fn part(&mut self, id: SessionId) {
|
fn part(&mut self, id: SessionId) {
|
||||||
let client = self.clients.remove(&id).expect("invalid session id");
|
let client = self.clients.remove(&id).expect("invalid session id");
|
||||||
|
|
||||||
|
|
@ -71,14 +84,6 @@ impl Room {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn join(&mut self, client: Client) {
|
|
||||||
self.notify_all(&Packet::ntf(JoinNtf {
|
|
||||||
who: client.session.clone(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
self.clients.insert(client.session.id, client);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn nick(&mut self, id: SessionId, nick: String) {
|
fn nick(&mut self, id: SessionId, nick: String) {
|
||||||
let who = {
|
let who = {
|
||||||
let client = self.client_mut(id);
|
let client = self.client_mut(id);
|
||||||
|
|
@ -112,6 +117,17 @@ impl Room {
|
||||||
|
|
||||||
message
|
message
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn who(&self, id: SessionId) -> (Session, Vec<Session>) {
|
||||||
|
let session = self.client(id).session.clone();
|
||||||
|
let others = self
|
||||||
|
.clients
|
||||||
|
.values()
|
||||||
|
.filter(|client| client.session.id != id)
|
||||||
|
.map(|client| client.session.clone())
|
||||||
|
.collect();
|
||||||
|
(session, others)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
@ -123,15 +139,6 @@ struct ServerSession {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ServerSession {
|
impl ServerSession {
|
||||||
fn new(tx: ConnTx, rx: ConnRx, room: Arc<Mutex<Room>>, session: Session) -> Self {
|
|
||||||
Self {
|
|
||||||
tx,
|
|
||||||
rx,
|
|
||||||
room,
|
|
||||||
session,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn handle_nick(&mut self, id: u64, cmd: NickCmd) -> anyhow::Result<()> {
|
async fn handle_nick(&mut self, id: u64, cmd: NickCmd) -> anyhow::Result<()> {
|
||||||
if let Some(reason) = util::check_nick(&cmd.nick) {
|
if let Some(reason) = util::check_nick(&cmd.nick) {
|
||||||
self.tx
|
self.tx
|
||||||
|
|
@ -165,8 +172,10 @@ impl ServerSession {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_who(&mut self, id: u64, cmd: WhoCmd) -> anyhow::Result<()> {
|
async fn handle_who(&mut self, id: u64, _cmd: WhoCmd) -> anyhow::Result<()> {
|
||||||
todo!()
|
let (you, others) = self.room.lock().await.who(self.session.id);
|
||||||
|
self.tx.send(&Packet::rpl(id, WhoRpl { you, others }))?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_packet(&mut self, packet: Packet) -> anyhow::Result<()> {
|
async fn handle_packet(&mut self, packet: Packet) -> anyhow::Result<()> {
|
||||||
|
|
@ -304,7 +313,6 @@ impl Server {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn on_conn(self, stream: TcpStream) -> anyhow::Result<()> {
|
async fn on_conn(self, stream: TcpStream) -> anyhow::Result<()> {
|
||||||
// TODO Ping-pong starting from the beginning (not just after hello)
|
|
||||||
println!("Connection from {}", stream.peer_addr().unwrap());
|
println!("Connection from {}", stream.peer_addr().unwrap());
|
||||||
let stream = tokio_tungstenite::accept_async(stream).await.unwrap();
|
let stream = tokio_tungstenite::accept_async(stream).await.unwrap();
|
||||||
let (tx, rx, maintenance) = conn::new(stream, Duration::from_secs(10))?;
|
let (tx, rx, maintenance) = conn::new(stream, Duration::from_secs(10))?;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue