fix: Websocket reconnection logic (#802, 889, #884)

This commit is contained in:
jamesread 2026-03-08 23:09:23 +00:00
parent 71bb999950
commit 24e8b48dc9
9 changed files with 59 additions and 10 deletions

View File

@ -1,5 +1,8 @@
import { buttonResults } from '../resources/vue/stores/buttonResults.js' import { buttonResults } from '../resources/vue/stores/buttonResults.js'
import { rateLimits } from '../resources/vue/stores/rateLimits.js' import { rateLimits } from '../resources/vue/stores/rateLimits.js'
import { connectionState } from '../resources/vue/stores/connectionState.js'
const RECONNECT_DELAY_MS = 3000
export function initWebsocket () { export function initWebsocket () {
window.addEventListener('EventOutputChunk', onOutputChunk) window.addEventListener('EventOutputChunk', onOutputChunk)
@ -16,9 +19,14 @@ async function reconnectWebsocket () {
return return
} }
connectionState.reconnecting = true
connectionState.connected = false
try { try {
window.websocketAvailable = true window.websocketAvailable = true
for await (const e of window.client.eventStream()) { for await (const e of window.client.eventStream()) {
connectionState.connected = true
connectionState.reconnecting = false
handleEvent(e) handleEvent(e)
} }
} catch (err) { } catch (err) {
@ -26,7 +34,11 @@ async function reconnectWebsocket () {
} }
window.websocketAvailable = false window.websocketAvailable = false
console.log('Reconnecting websocket...') connectionState.connected = false
console.log('Reconnecting websocket in ' + RECONNECT_DELAY_MS + 'ms...')
setTimeout(() => {
reconnectWebsocket()
}, RECONNECT_DELAY_MS)
} }
function handleEvent (msg) { function handleEvent (msg) {

View File

@ -50,7 +50,7 @@
<a href="#" @click.prevent="openThemeDialog">{{ currentThemeName }}</a> <a href="#" @click.prevent="openThemeDialog">{{ currentThemeName }}</a>
</span> </span>
<span>{{ t('connected') }}</span> <span :title="connectionStatusTitle">{{ connectionStatusLabel }}</span>
</p> </p>
<p v-if="showVersionNumber"> <p v-if="showVersionNumber">
<a id="available-version" href="http://olivetin.app" target="_blank" hidden>?</a> <a id="available-version" href="http://olivetin.app" target="_blank" hidden>?</a>
@ -107,6 +107,7 @@ import { DashboardSquare01Icon } from '@hugeicons/core-free-icons'
import logoUrl from '../../OliveTinLogo.png'; import logoUrl from '../../OliveTinLogo.png';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import combinedTranslations from '../../../lang/combined_output.json'; import combinedTranslations from '../../../lang/combined_output.json';
import { connectionState } from './stores/connectionState.js';
const { t, locale } = useI18n(); const { t, locale } = useI18n();
@ -116,7 +117,6 @@ const sidebar = ref(null);
const navigation = ref(null); const navigation = ref(null);
const username = ref('notset'); const username = ref('notset');
const isLoggedIn = ref(false); const isLoggedIn = ref(false);
const serverConnection = ref(true);
const currentVersion = ref('?'); const currentVersion = ref('?');
const pageTitle = ref('OliveTin'); const pageTitle = ref('OliveTin');
const bannerMessage = ref(''); const bannerMessage = ref('');
@ -130,6 +130,18 @@ const showVersionNumber = ref(true)
const showLoginLink = ref(true) const showLoginLink = ref(true)
const sectionNavigationStyle = ref('sidebar') const sectionNavigationStyle = ref('sidebar')
const connectionStatusLabel = computed(() => {
if (connectionState.connected) {
return t('connected')
}
if (connectionState.reconnecting) {
return t('reconnecting')
}
return t('disconnected')
})
const connectionStatusTitle = computed(() => connectionStatusLabel.value)
const languageDialog = ref(null) const languageDialog = ref(null)
const browserLanguages = ref([]) const browserLanguages = ref([])
@ -404,7 +416,6 @@ function handleThemeDialogClick(event) {
window.updateHeaderFromInit = updateHeaderFromInit window.updateHeaderFromInit = updateHeaderFromInit
onMounted(() => { onMounted(() => {
serverConnection.value = true;
updateHeaderFromInit() updateHeaderFromInit()
// Initialize selected language from stored preference // Initialize selected language from stored preference

View File

@ -0,0 +1,6 @@
import { reactive } from 'vue'
export const connectionState = reactive({
connected: false,
reconnecting: false
})

View File

@ -20,6 +20,7 @@
"diagnostics.unknown": "Unbekannt", "diagnostics.unknown": "Unbekannt",
"diagnostics.useragent-data-error": "Fehler beim Abrufen von userAgentData", "diagnostics.useragent-data-error": "Fehler beim Abrufen von userAgentData",
"diagnostics.where-to-find-help": "Wo Sie Hilfe finden", "diagnostics.where-to-find-help": "Wo Sie Hilfe finden",
"disconnected": "Getrennt",
"docs": "Dokumentation", "docs": "Dokumentation",
"language-dialog.browser-languages": "Browser-Sprachen", "language-dialog.browser-languages": "Browser-Sprachen",
"language-dialog.close": "Schließen", "language-dialog.close": "Schließen",
@ -47,6 +48,7 @@
"nav.entities": "Entitäten", "nav.entities": "Entitäten",
"nav.logs": "Protokolle", "nav.logs": "Protokolle",
"raise-issue": "Ein Problem melden auf GitHub", "raise-issue": "Ein Problem melden auf GitHub",
"reconnecting": "Verbinde erneut…",
"return-to-index": "Zurück zur Startseite", "return-to-index": "Zurück zur Startseite",
"search-filter": "Filter aktuelle Seite", "search-filter": "Filter aktuelle Seite",
"theme-dialog.close": "Schließen", "theme-dialog.close": "Schließen",
@ -73,6 +75,7 @@
"diagnostics.unknown": "Unknown", "diagnostics.unknown": "Unknown",
"diagnostics.useragent-data-error": "Error retrieving userAgentData", "diagnostics.useragent-data-error": "Error retrieving userAgentData",
"diagnostics.where-to-find-help": "Where to find help", "diagnostics.where-to-find-help": "Where to find help",
"disconnected": "Disconnected",
"docs": "Documentation", "docs": "Documentation",
"language-dialog.browser-languages": "Browser languages", "language-dialog.browser-languages": "Browser languages",
"language-dialog.close": "Close", "language-dialog.close": "Close",
@ -100,6 +103,7 @@
"nav.entities": "Entities", "nav.entities": "Entities",
"nav.logs": "Logs", "nav.logs": "Logs",
"raise-issue": "Raise an issue on GitHub", "raise-issue": "Raise an issue on GitHub",
"reconnecting": "Reconnecting…",
"return-to-index": "Return to index", "return-to-index": "Return to index",
"search-filter": "Filter current page", "search-filter": "Filter current page",
"theme-dialog.close": "Close", "theme-dialog.close": "Close",
@ -126,6 +130,7 @@
"diagnostics.unknown": "Desconocido", "diagnostics.unknown": "Desconocido",
"diagnostics.useragent-data-error": "Error al recuperar userAgentData", "diagnostics.useragent-data-error": "Error al recuperar userAgentData",
"diagnostics.where-to-find-help": "Dónde encontrar ayuda", "diagnostics.where-to-find-help": "Dónde encontrar ayuda",
"disconnected": "Desconectado",
"docs": "Documentación", "docs": "Documentación",
"language-dialog.browser-languages": "Idiomas del navegador", "language-dialog.browser-languages": "Idiomas del navegador",
"language-dialog.close": "Cerrar", "language-dialog.close": "Cerrar",
@ -153,6 +158,7 @@
"nav.entities": "Entidades", "nav.entities": "Entidades",
"nav.logs": "Registros", "nav.logs": "Registros",
"raise-issue": "Reportar un problema en GitHub", "raise-issue": "Reportar un problema en GitHub",
"reconnecting": "Reconectando…",
"return-to-index": "Volver a la página principal", "return-to-index": "Volver a la página principal",
"search-filter": "Filtrar página actual", "search-filter": "Filtrar página actual",
"theme-dialog.close": "Cerrar", "theme-dialog.close": "Cerrar",
@ -179,6 +185,7 @@
"diagnostics.unknown": "Sconosciuto", "diagnostics.unknown": "Sconosciuto",
"diagnostics.useragent-data-error": "Errore nel recupero di userAgentData", "diagnostics.useragent-data-error": "Errore nel recupero di userAgentData",
"diagnostics.where-to-find-help": "Dove trovare aiuto", "diagnostics.where-to-find-help": "Dove trovare aiuto",
"disconnected": "Disconnesso",
"docs": "Documentazione", "docs": "Documentazione",
"language-dialog.browser-languages": "Lingue del browser", "language-dialog.browser-languages": "Lingue del browser",
"language-dialog.close": "Chiudi", "language-dialog.close": "Chiudi",
@ -206,6 +213,7 @@
"nav.entities": "Entità", "nav.entities": "Entità",
"nav.logs": "Registri", "nav.logs": "Registri",
"raise-issue": "Segnala un problema su GitHub", "raise-issue": "Segnala un problema su GitHub",
"reconnecting": "Riconnessione…",
"return-to-index": "Torna alla pagina principale", "return-to-index": "Torna alla pagina principale",
"search-filter": "Filtra la pagina corrente", "search-filter": "Filtra la pagina corrente",
"theme-dialog.close": "Chiudi", "theme-dialog.close": "Chiudi",
@ -232,6 +240,7 @@
"diagnostics.unknown": "未知", "diagnostics.unknown": "未知",
"diagnostics.useragent-data-error": "检索 userAgentData 时出错", "diagnostics.useragent-data-error": "检索 userAgentData 时出错",
"diagnostics.where-to-find-help": "在哪里找到帮助", "diagnostics.where-to-find-help": "在哪里找到帮助",
"disconnected": "已断开连接",
"docs": "文档", "docs": "文档",
"language-dialog.browser-languages": "浏览器语言", "language-dialog.browser-languages": "浏览器语言",
"language-dialog.close": "关闭", "language-dialog.close": "关闭",
@ -259,6 +268,7 @@
"nav.entities": "实体", "nav.entities": "实体",
"nav.logs": "日志", "nav.logs": "日志",
"raise-issue": "在 GitHub 上报告问题", "raise-issue": "在 GitHub 上报告问题",
"reconnecting": "正在重新连接…",
"return-to-index": "返回首页", "return-to-index": "返回首页",
"search-filter": "过滤当前页面", "search-filter": "过滤当前页面",
"theme-dialog.close": "关闭", "theme-dialog.close": "关闭",

View File

@ -6,6 +6,8 @@ translations:
nav.entities: Entitäten nav.entities: Entitäten
nav.diagnostics: Diagnostik nav.diagnostics: Diagnostik
connected: Verbunden connected: Verbunden
disconnected: Getrennt
reconnecting: Verbinde erneut…
login-button: Login login-button: Login
raise-issue: Ein Problem melden auf GitHub raise-issue: Ein Problem melden auf GitHub
docs: Dokumentation docs: Dokumentation

View File

@ -8,6 +8,8 @@ translations:
nav.entities: Entities nav.entities: Entities
nav.diagnostics: Diagnostics nav.diagnostics: Diagnostics
connected: Connected connected: Connected
disconnected: Disconnected
reconnecting: Reconnecting…
login-button: Login login-button: Login
logs.title: Logs logs.title: Logs
logs.page-description: This is a list of logs from actions that have been executed. You can filter the list by action title. logs.page-description: This is a list of logs from actions that have been executed. You can filter the list by action title.

View File

@ -6,6 +6,8 @@ translations:
nav.entities: Entidades nav.entities: Entidades
nav.diagnostics: Diagnósticos nav.diagnostics: Diagnósticos
connected: Conectado connected: Conectado
disconnected: Desconectado
reconnecting: Reconectando…
login-button: Iniciar sesión login-button: Iniciar sesión
raise-issue: Reportar un problema en GitHub raise-issue: Reportar un problema en GitHub
docs: Documentación docs: Documentación

View File

@ -7,6 +7,8 @@ translations:
nav.diagnostics: Diagnostica nav.diagnostics: Diagnostica
docs: Documentazione docs: Documentazione
connected: Connesso connected: Connesso
disconnected: Disconnesso
reconnecting: Riconnessione…
login-button: Login login-button: Login
raise-issue: Segnala un problema su GitHub raise-issue: Segnala un problema su GitHub
logs.title: Registri logs.title: Registri

View File

@ -6,6 +6,8 @@ translations:
nav.entities: 实体 nav.entities: 实体
nav.diagnostics: 诊断 nav.diagnostics: 诊断
connected: 已连接 connected: 已连接
disconnected: 已断开连接
reconnecting: 正在重新连接…
login-button: 登录 login-button: 登录
raise-issue: 在 GitHub 上报告问题 raise-issue: 在 GitHub 上报告问题
docs: 文档 docs: 文档