diff --git a/crates/app/src/public/html/chats/app.html b/crates/app/src/public/html/chats/app.html
index 80f5512..e978383 100644
--- a/crates/app/src/public/html/chats/app.html
+++ b/crates/app/src/public/html/chats/app.html
@@ -135,7 +135,6 @@
{{ icon "rss" }}
{{ channel.title }}
@@ -494,23 +493,28 @@
const data = JSON.parse(msg.data);
if (msg.method === "Message" && window.CURRENT_PAGE === 0) {
- const element = document.createElement("div");
- element.style.display = "contents";
- element.innerHTML = await (
- await fetch(
- "/chats/{{ selected_community }}/{{ selected_channel }}/_render",
- {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
+ if (document.getElementById("stream_body")) {
+ const element = document.createElement("div");
+ element.style.display = "contents";
+ element.innerHTML = await (
+ await fetch(
+ "/chats/{{ selected_community }}/{{ selected_channel }}/_render",
+ {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({ data: msg.data }),
},
- body: JSON.stringify({ data: msg.data }),
- },
- )
- ).text();
+ )
+ ).text();
- document.getElementById("stream_body").prepend(element);
- clean_text();
+ document.getElementById("stream_body").prepend(element);
+ clean_text();
+ } else {
+ console.log("abandoned remote");
+ socket.close();
+ }
} else if (msg.method === "Delete") {
if (document.getElementById(`message-${data.id}`)) {
document.getElementById(`message-${data.id}`).remove();
diff --git a/crates/app/src/routes/api/v1/channels/messages.rs b/crates/app/src/routes/api/v1/channels/messages.rs
index 02f5d71..67d75f9 100644
--- a/crates/app/src/routes/api/v1/channels/messages.rs
+++ b/crates/app/src/routes/api/v1/channels/messages.rs
@@ -16,7 +16,7 @@ use tetratto_core::{
ApiReturn, Error,
},
};
-use std::sync::mpsc;
+use std::{sync::mpsc, time::Duration};
use crate::{get_user_from_token, routes::api::v1::CreateMessage, State};
use serde::Deserialize;
use futures_util::{sink::SinkExt, stream::StreamExt};
@@ -47,7 +47,7 @@ pub async fn handle_socket(socket: WebSocket, state: State, channel_id: usize) {
tokio::spawn(async move {
while let Ok(message) = receiver.recv() {
if message == "Close" {
- sink.close().await.unwrap();
+ let _ = sink.close().await;
drop(receiver);
break;
}
@@ -58,6 +58,20 @@ pub async fn handle_socket(socket: WebSocket, state: State, channel_id: usize) {
}
});
+ // ping
+ let ping_sender = sender.clone();
+ tokio::spawn(async move {
+ let mut heartbeat = tokio::time::interval(Duration::from_secs(30));
+
+ loop {
+ heartbeat.tick().await;
+ if ping_sender.send("Ping".to_string()).is_err() {
+ // remote has abandoned us
+ break;
+ }
+ }
+ });
+
// ...
let mut user: Option = None;
let mut con = db.2.clone().get_con().await;