From 531c6d1bf701af8548bc764cd977942f65bcf76f Mon Sep 17 00:00:00 2001 From: curly Date: Tue, 28 Feb 2023 10:32:16 -0700 Subject: terrible ws implementation --- Cargo.lock | 138 ++++++++++++++++++++++++++++++++++++++++++++++++-- Cargo.toml | 4 +- TODO | 5 ++ src/database.rs | 19 +++++-- src/database/types.rs | 18 ++++++- src/main.rs | 80 +++++++++++++++++++++++++++-- 6 files changed, 250 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7ad81ff..16ff70a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -104,6 +104,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + [[package]] name = "base64" version = "0.20.0" @@ -137,6 +143,12 @@ version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + [[package]] name = "bytes" version = "1.3.0" @@ -197,7 +209,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" dependencies = [ "aes-gcm", - "base64", + "base64 0.20.0", "hkdf", "hmac", "percent-encoding", @@ -375,6 +387,15 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "form_urlencoded" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" +dependencies = [ + "percent-encoding", +] + [[package]] name = "futures" version = "0.3.25" @@ -633,6 +654,16 @@ dependencies = [ "cxx-build", ] +[[package]] +name = "idna" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "indexmap" version = "1.9.2" @@ -1143,12 +1174,14 @@ dependencies = [ [[package]] name = "rocket_test" -version = "0.2.5" +version = "0.3.0" dependencies = [ "chrono", "rocket", "serde", + "serde_json", "sqlite", + "tungstenite", ] [[package]] @@ -1203,15 +1236,26 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.91" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883" +checksum = "cad406b69c91885b5107daf2c29572f6c8cdb3c66826821e286c533490c0bc76" dependencies = [ "itoa", "ryu", "serde", ] +[[package]] +name = "sha1" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "sha2" version = "0.10.6" @@ -1360,6 +1404,26 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "thiserror" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "thread_local" version = "1.1.4" @@ -1407,6 +1471,21 @@ dependencies = [ "time-core", ] +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tokio" version = "1.24.2" @@ -1545,6 +1624,25 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +[[package]] +name = "tungstenite" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30ee6ab729cd4cf0fd55218530c4522ed30b7b6081752839b68fcec8d0960788" +dependencies = [ + "base64 0.13.1", + "byteorder", + "bytes", + "http", + "httparse", + "log", + "rand", + "sha1", + "thiserror", + "url", + "utf-8", +] + [[package]] name = "typenum" version = "1.16.0" @@ -1570,12 +1668,27 @@ dependencies = [ "version_check", ] +[[package]] +name = "unicode-bidi" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54675592c1dbefd78cbd98db9bacd89886e1ca50692a0692baefffdeb92dd58" + [[package]] name = "unicode-ident" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + [[package]] name = "unicode-width" version = "0.1.10" @@ -1598,6 +1711,23 @@ dependencies = [ "subtle", ] +[[package]] +name = "url" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + [[package]] name = "valuable" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 1ef8bfc..e67a995 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,12 +1,14 @@ [package] name = "rocket_test" -version = "0.2.5" +version = "0.3.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] serde = "1.0.130" +serde_json = {version = "1.0.93", features = ["std"]} chrono = "0.4.23" sqlite = "0.30.4" rocket = {version = "0.5.0-rc.2", features = ["json"]} +tungstenite = "0.18.0" \ No newline at end of file diff --git a/TODO b/TODO index 33dd38b..de8e4cf 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,10 @@ Authentication +Websocket implementation is terrible: Probably need to rewrite everything to + use tokio and maybe get rid of rocket +Database should probably be on its own thread??? +Need to rewrite lots of stuff + Add Channels Add DM'ing diff --git a/src/database.rs b/src/database.rs index 74d9c1a..48c6b12 100644 --- a/src/database.rs +++ b/src/database.rs @@ -6,6 +6,7 @@ use super::*; pub struct Database { db: Connection, + newest_message_id: Option, } impl Database { pub fn get_message(&self, id: usize) -> Option { @@ -40,11 +41,18 @@ impl Database { pub fn get_next_message_id(&self) -> UID { UID::from(self.get_table_length("messages")) } - pub fn get_message_newest_id(&self) -> Option { - match self.get_table_length("messages") { - 0 => None, - n => Some(UID::new(n - 1)), + pub fn get_message_newest_id(&mut self) -> Option { + match self.newest_message_id { + None => { + self.newest_message_id = match self.get_table_length("messages") { + 0 => None, + n => Some(UID::new(n - 1)), + } + }, + Some(_) => () } + + self.newest_message_id } fn message_from_row(&self, row: sqlite::Row) -> Message{ @@ -137,6 +145,8 @@ impl Database { } } + self.newest_message_id = Some(msg.id()); + Ok(msg.id()) } @@ -379,6 +389,7 @@ impl Database { Database { db: db, + newest_message_id: None } } } \ No newline at end of file diff --git a/src/database/types.rs b/src/database/types.rs index 4656e49..65aca05 100644 --- a/src/database/types.rs +++ b/src/database/types.rs @@ -234,4 +234,20 @@ impl ReceiveMessage { pub struct ReceiveUpdateField {pub user: UID, pub field: DataField, pub data: String} #[derive(Deserialize, Clone)] -pub struct ReceiveStatus {pub user: UID, pub status: Status} \ No newline at end of file +pub struct ReceiveStatus {pub user: UID, pub status: Status} + +pub enum BinaryMessage { + GetMessageNewestId +} +impl std::convert::From<&[u8]> for BinaryMessage { + fn from(t: &[u8]) -> BinaryMessage { + match t { + _ => BinaryMessage::GetMessageNewestId, + } + } +} + +#[derive(Serialize, Deserialize)] +pub enum WebSocketMessage { + NewMessage +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index af0234a..fd76ec7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,12 +4,13 @@ mod database; use rocket::serde::json::Json; use rocket::State; -use std::sync::Mutex; +use std::sync::{Mutex, Arc}; use database::types::*; +use tungstenite::accept; struct SharedDB { - sdb: Mutex + sdb: Arc> } #[derive(serde::Serialize)] @@ -64,7 +65,7 @@ fn get_message_list(id_start: u64, id_end: u64, db: &State) -> Json) -> Json> { - let lock = db.sdb.lock().unwrap(); + let mut lock = db.sdb.lock().unwrap(); match lock.get_message_newest_id() { Some(n) => Json(Response(Ok(n))), None => Json(Response(Err("No messages"))) @@ -145,6 +146,7 @@ fn api_index(db: &State) -> Json { } + #[derive(serde::Serialize)] struct HitCount { c: usize @@ -152,6 +154,75 @@ struct HitCount { #[launch] fn rocket() -> _ { + let database = std::sync::Arc::new(Mutex::new(database::Database::new())); + + let websocketdb = Arc::clone(&database); + let rocketdb = Arc::clone(&database); + + std::thread::spawn(move || { + let listen = std::net::TcpListener::bind("127.0.0.1:8001").unwrap(); + + loop { + for connection in listen.incoming() { + + let wsconnectiondb = Arc::clone(&websocketdb); + std::thread::spawn(move || { + let mut websocket = accept(connection.unwrap()).unwrap(); + let mut newest = 0; + + loop { + // TX + let mut db = wsconnectiondb.lock().unwrap(); + let local_newest = match db.get_message_newest_id() { + Some(n) => n.into(), + None => 0 + }; + drop(db); + + if local_newest > newest { + let m = serde_json::to_string(&WebSocketMessage::NewMessage).unwrap(); + websocket.write_message(tungstenite::Message::text(m)).unwrap(); + newest = local_newest; + } + + std::thread::sleep(std::time::Duration::from_millis(100)); + + // RX + // let _ = match websocket.read_message() { + // Ok(n) => n, + // Err(_) => {println!("closed"); break} + // }; + + // if msg.is_binary() { + // if msg.len() > 0 { + // match msg.into_data()[0..=1].into() { + // BinaryMessage::GetMessageNewestId => { + // let db = wsconnectiondb.lock().unwrap(); + // let m = db.get_message_newest_id(); + // drop(db); + + // let m = serde_json::to_string(&m).unwrap(); + // websocket.write_message(tungstenite::Message::text(m)).unwrap(); + // }, + // // Return error of unsupported data + // _ => (), + // } + // } else { + // // Return error of empty data + // websocket.write_message(msg).unwrap(); + // } + + // } else if msg.is_text() { + // println!("{}", msg.into_text().unwrap()); + // } + + } + + }); + } + } + }); + rocket::build() .mount("/api", routes![ get_message, @@ -167,7 +238,8 @@ fn rocket() -> _ { get_message_list, set_user_data, set_user_status, + ]) .mount("/", routes![api_index]) - .manage(SharedDB{sdb: Mutex::new(database::Database::new())}) + .manage(SharedDB{sdb: rocketdb}) } \ No newline at end of file -- cgit v1.2.3