add: websocket pings

This commit is contained in:
trisua 2025-04-27 23:59:24 -04:00
parent 25d2d25fbc
commit d669cd4d4e
2 changed files with 36 additions and 18 deletions

View file

@ -135,7 +135,6 @@
<a <a
class="w-full justify-start button {% if selected_channel == channel.id %}quaternary{% else %}camo{% endif %}" class="w-full justify-start button {% if selected_channel == channel.id %}quaternary{% else %}camo{% endif %}"
href="/chats/{{ selected_community }}/{{ channel.id }}" href="/chats/{{ selected_community }}/{{ channel.id }}"
data-turbo="false"
> >
{{ icon "rss" }} {{ icon "rss" }}
<b class="name shortest">{{ channel.title }}</b> <b class="name shortest">{{ channel.title }}</b>
@ -494,23 +493,28 @@
const data = JSON.parse(msg.data); const data = JSON.parse(msg.data);
if (msg.method === "Message" && window.CURRENT_PAGE === 0) { if (msg.method === "Message" && window.CURRENT_PAGE === 0) {
const element = document.createElement("div"); if (document.getElementById("stream_body")) {
element.style.display = "contents"; const element = document.createElement("div");
element.innerHTML = await ( element.style.display = "contents";
await fetch( element.innerHTML = await (
"/chats/{{ selected_community }}/{{ selected_channel }}/_render", await fetch(
{ "/chats/{{ selected_community }}/{{ selected_channel }}/_render",
method: "POST", {
headers: { method: "POST",
"Content-Type": "application/json", 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); document.getElementById("stream_body").prepend(element);
clean_text(); clean_text();
} else {
console.log("abandoned remote");
socket.close();
}
} else if (msg.method === "Delete") { } else if (msg.method === "Delete") {
if (document.getElementById(`message-${data.id}`)) { if (document.getElementById(`message-${data.id}`)) {
document.getElementById(`message-${data.id}`).remove(); document.getElementById(`message-${data.id}`).remove();

View file

@ -16,7 +16,7 @@ use tetratto_core::{
ApiReturn, Error, ApiReturn, Error,
}, },
}; };
use std::sync::mpsc; use std::{sync::mpsc, time::Duration};
use crate::{get_user_from_token, routes::api::v1::CreateMessage, State}; use crate::{get_user_from_token, routes::api::v1::CreateMessage, State};
use serde::Deserialize; use serde::Deserialize;
use futures_util::{sink::SinkExt, stream::StreamExt}; 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 { tokio::spawn(async move {
while let Ok(message) = receiver.recv() { while let Ok(message) = receiver.recv() {
if message == "Close" { if message == "Close" {
sink.close().await.unwrap(); let _ = sink.close().await;
drop(receiver); drop(receiver);
break; 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<User> = None; let mut user: Option<User> = None;
let mut con = db.2.clone().get_con().await; let mut con = db.2.clone().get_con().await;