forked from jmug/stoatchat
Re-write notifications system.
This commit is contained in:
119
src/notifications/ws.rs
Normal file
119
src/notifications/ws.rs
Normal file
@@ -0,0 +1,119 @@
|
||||
use super::state::{self, StateResult};
|
||||
|
||||
use serde_json::{from_str, json, Value};
|
||||
use std::env;
|
||||
use ulid::Ulid;
|
||||
use ws::{listen, CloseCode, Error, Handler, Handshake, Message, Result, Sender};
|
||||
|
||||
struct Server {
|
||||
sender: Sender,
|
||||
user_id: Option<String>,
|
||||
id: String,
|
||||
}
|
||||
|
||||
impl Handler for Server {
|
||||
fn on_open(&mut self, _: Handshake) -> Result<()> {
|
||||
state::add_connection(self.id.clone(), self.sender.clone());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn on_message(&mut self, msg: Message) -> Result<()> {
|
||||
if let Message::Text(text) = msg {
|
||||
if let Ok(data) = from_str(&text) as std::result::Result<Value, _> {
|
||||
if let Value::String(packet_type) = &data["type"] {
|
||||
if packet_type == "authenticate" {
|
||||
if self.user_id.is_some() {
|
||||
self.sender.send(
|
||||
json!({
|
||||
"type": "authenticate",
|
||||
"success": false,
|
||||
"error": "Already authenticated!"
|
||||
})
|
||||
.to_string(),
|
||||
)
|
||||
} else if let Value::String(token) = &data["token"] {
|
||||
let mut state = unsafe { state::DATA.get().unwrap().write().unwrap() };
|
||||
|
||||
match state.try_authenticate(self.id.clone(), token.to_string()) {
|
||||
StateResult::Success(user_id) => {
|
||||
self.user_id = Some(user_id);
|
||||
self.sender.send(
|
||||
json!({
|
||||
"type": "authenticate",
|
||||
"success": true,
|
||||
})
|
||||
.to_string(),
|
||||
)
|
||||
}
|
||||
StateResult::DatabaseError => self.sender.send(
|
||||
json!({
|
||||
"type": "authenticate",
|
||||
"success": false,
|
||||
"error": "Had database error."
|
||||
})
|
||||
.to_string(),
|
||||
),
|
||||
StateResult::InvalidToken => self.sender.send(
|
||||
json!({
|
||||
"type": "authenticate",
|
||||
"success": false,
|
||||
"error": "Invalid token."
|
||||
})
|
||||
.to_string(),
|
||||
),
|
||||
}
|
||||
} else {
|
||||
self.sender.send(
|
||||
json!({
|
||||
"type": "authenticate",
|
||||
"success": false,
|
||||
"error": "Token not present."
|
||||
})
|
||||
.to_string(),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn on_close(&mut self, _code: CloseCode, _reason: &str) {
|
||||
unsafe {
|
||||
state::DATA
|
||||
.get()
|
||||
.unwrap()
|
||||
.write()
|
||||
.unwrap()
|
||||
.disconnect(self.user_id.clone(), self.id.clone());
|
||||
}
|
||||
|
||||
println!("User disconnected. [{}]", self.id);
|
||||
}
|
||||
|
||||
fn on_error(&mut self, err: Error) {
|
||||
println!("The server encountered an error: {:?}", err);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn launch_server() {
|
||||
state::init();
|
||||
|
||||
listen(
|
||||
env::var("WS_HOST").unwrap_or("0.0.0.0:9999".to_string()),
|
||||
|sender| Server {
|
||||
sender,
|
||||
user_id: None,
|
||||
id: Ulid::new().to_string(),
|
||||
},
|
||||
)
|
||||
.unwrap()
|
||||
}
|
||||
Reference in New Issue
Block a user