Switch to async-std, refractor notifications code.

This commit is contained in:
Paul Makles
2020-12-28 17:52:22 +00:00
parent 6253a91276
commit c748b4349b
16 changed files with 498 additions and 809 deletions

View File

@@ -0,0 +1,67 @@
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(tag = "type")]
pub enum Notification {
MessageCreate {
id: String,
nonce: Option<String>,
channel: String,
author: String,
content: String,
},
MessageEdit {
id: String,
channel: String,
author: String,
content: String,
},
MessageDelete {
id: String,
},
GroupUserJoin {
id: String,
user: String,
},
GroupUserLeave {
id: String,
user: String,
},
GuildUserJoin {
id: String,
user: String,
},
GuildUserLeave {
id: String,
user: String,
banned: bool,
},
GuildChannelCreate {
id: String,
channel: String,
name: String,
description: String,
},
GuildChannelDelete {
id: String,
channel: String,
},
GuildDelete {
id: String,
},
UserRelationship {
id: String,
user: String,
status: i32,
}
}

57
src/notifications/hive.rs Normal file
View File

@@ -0,0 +1,57 @@
use super::events::Notification;
// use super::websocket;
use crate::database::get_collection;
use hive_pubsub::backend::mongo::MongodbPubSub;
use hive_pubsub::PubSub;
use once_cell::sync::OnceCell;
use serde_json::to_string;
use log::{error, debug};
static HIVE: OnceCell<MongodbPubSub<String, String, Notification>> = OnceCell::new();
pub async fn init_hive() {
let hive = MongodbPubSub::new(
|_ids, notification| {
if let Ok(data) = to_string(&notification) {
debug!("Pushing out notification. {}", data);
// ! FIXME: push to websocket
} else {
error!("Failed to serialise notification.");
}
},
get_collection("hive"),
);
if HIVE.set(hive).is_err() {
panic!("Failed to set global pubsub instance.");
}
}
pub fn publish(topic: &String, data: Notification) -> Result<(), String> {
let hive = HIVE.get().unwrap();
hive.publish(topic, data)
}
pub fn subscribe(user: String, topics: Vec<String>) -> Result<(), String> {
let hive = HIVE.get().unwrap();
for topic in topics {
hive.subscribe(user.clone(), topic)?;
}
Ok(())
}
pub fn drop_user(user: &String) -> Result<(), String> {
let hive = HIVE.get().unwrap();
hive.drop_client(user)?;
Ok(())
}
pub fn drop_topic(topic: &String) -> Result<(), String> {
let hive = HIVE.get().unwrap();
hive.drop_topic(topic)?;
Ok(())
}

3
src/notifications/mod.rs Normal file
View File

@@ -0,0 +1,3 @@
pub mod websocket;
pub mod events;
pub mod hive;

View File

@@ -0,0 +1,28 @@
use crate::util::variables::WS_HOST;
use log::info;
use async_std::task;
use futures::prelude::*;
use async_std::net::{TcpListener, TcpStream};
pub async fn launch_server() {
let try_socket = TcpListener::bind(WS_HOST.to_string()).await;
let listener = try_socket.expect("Failed to bind");
info!("Listening on: {}", *WS_HOST);
while let Ok((stream, _)) = listener.accept().await {
task::spawn(accept(stream));
}
}
async fn accept(stream: TcpStream) {
let addr = stream.peer_addr().expect("Connected streams should have a peer address.");
let ws_stream = async_tungstenite::accept_async(stream)
.await
.expect("Error during websocket handshake.");
info!("User established WebSocket connection from {}.", addr);
let (write, read) = ws_stream.split();
read.forward(write).await.expect("Failed to forward message")
}