Răsfoiți Sursa

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

jamesread 3 luni în urmă
părinte
comite
24e8b48dc9

+ 13 - 1
frontend/js/websocket.js

@@ -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) {

+ 14 - 3
frontend/resources/vue/App.vue

@@ -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

+ 6 - 0
frontend/resources/vue/stores/connectionState.js

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

+ 11 - 1
lang/combined_output.json

@@ -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": "关闭",
@@ -267,4 +277,4 @@
             "welcome": "欢迎使用 OliveTin"
             "welcome": "欢迎使用 OliveTin"
         }
         }
     }
     }
-}
+}

+ 3 - 1
lang/de-DE.yaml

@@ -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
@@ -50,4 +52,4 @@ translations:
   language-dialog.close: Schließen
   language-dialog.close: Schließen
   theme-dialog.title: Design auswählen
   theme-dialog.title: Design auswählen
   theme-dialog.default: Standard-Design
   theme-dialog.default: Standard-Design
-  theme-dialog.close: Schließen
+  theme-dialog.close: Schließen

+ 3 - 1
lang/en.yaml

@@ -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.
@@ -50,4 +52,4 @@ translations:
   language-dialog.close: Close
   language-dialog.close: Close
   theme-dialog.title: Select Theme
   theme-dialog.title: Select Theme
   theme-dialog.default: Default Theme
   theme-dialog.default: Default Theme
-  theme-dialog.close: Close
+  theme-dialog.close: Close

+ 3 - 1
lang/es-ES.yaml

@@ -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
@@ -50,4 +52,4 @@ translations:
   language-dialog.close: Cerrar
   language-dialog.close: Cerrar
   theme-dialog.title: Seleccionar tema
   theme-dialog.title: Seleccionar tema
   theme-dialog.default: Tema Predeterminado
   theme-dialog.default: Tema Predeterminado
-  theme-dialog.close: Cerrar
+  theme-dialog.close: Cerrar

+ 3 - 1
lang/it-IT.yaml

@@ -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
@@ -50,4 +52,4 @@ translations:
   language-dialog.close: Chiudi
   language-dialog.close: Chiudi
   theme-dialog.title: Seleziona tema
   theme-dialog.title: Seleziona tema
   theme-dialog.default: Tema Predefinito
   theme-dialog.default: Tema Predefinito
-  theme-dialog.close: Chiudi
+  theme-dialog.close: Chiudi

+ 3 - 1
lang/zh-Hans-CN.yaml

@@ -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: 文档
@@ -50,4 +52,4 @@ translations:
   diagnostics.copy-to-clipboard: 复制到剪贴板
   diagnostics.copy-to-clipboard: 复制到剪贴板
   diagnostics.copied: 已复制!
   diagnostics.copied: 已复制!
   diagnostics.unknown: 未知
   diagnostics.unknown: 未知
-  diagnostics.useragent-data-error: 检索 userAgentData 时出错
+  diagnostics.useragent-data-error: 检索 userAgentData 时出错