Compare commits
2
Commits
07c17fbd2c
...
43831d31f6
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
43831d31f6 | ||
|
|
bf7eda3f6a |
No files matched your search
+10
-3
@@ -1,5 +1,5 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted, onUnmounted, ref } from 'vue'
|
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||||
import * as api from './api'
|
import * as api from './api'
|
||||||
import BacktestPanel from './components/BacktestPanel.vue'
|
import BacktestPanel from './components/BacktestPanel.vue'
|
||||||
import EquityChart from './components/EquityChart.vue'
|
import EquityChart from './components/EquityChart.vue'
|
||||||
@@ -37,6 +37,10 @@ const equityPoints = ref([])
|
|||||||
const busy = ref(false)
|
const busy = ref(false)
|
||||||
const connected = ref(false)
|
const connected = ref(false)
|
||||||
const socketError = ref('')
|
const socketError = ref('')
|
||||||
|
const socketFailures = ref(0)
|
||||||
|
// After a few failed socket attempts (some mobile browsers/DPIs refuse wss://),
|
||||||
|
// stop advertising "reconnecting" and rely on the 5s REST poll instead.
|
||||||
|
const usePolling = computed(() => socketFailures.value >= 3)
|
||||||
|
|
||||||
let socket
|
let socket
|
||||||
let pollTimer
|
let pollTimer
|
||||||
@@ -139,6 +143,7 @@ onMounted(async () => {
|
|||||||
},
|
},
|
||||||
onClose: () => (connected.value = false),
|
onClose: () => (connected.value = false),
|
||||||
onError: (code) => {
|
onError: (code) => {
|
||||||
|
socketFailures.value += 1
|
||||||
if (code === 1008) socketError.value = 'rejected by the server (token/auth)'
|
if (code === 1008) socketError.value = 'rejected by the server (token/auth)'
|
||||||
else socketError.value = `socket closed (code ${code})`
|
else socketError.value = `socket closed (code ${code})`
|
||||||
},
|
},
|
||||||
@@ -166,9 +171,11 @@ onUnmounted(() => {
|
|||||||
<span class="flex items-center gap-1.5 text-xs text-slate-400">
|
<span class="flex items-center gap-1.5 text-xs text-slate-400">
|
||||||
<span
|
<span
|
||||||
class="h-2 w-2 rounded-full"
|
class="h-2 w-2 rounded-full"
|
||||||
:class="connected ? 'bg-emerald-400' : 'bg-slate-500'"
|
:class="connected ? 'bg-emerald-400' : usePolling ? 'bg-sky-400' : 'bg-slate-500'"
|
||||||
></span>
|
></span>
|
||||||
{{ connected ? 'live' : 'reconnecting' }}
|
<template v-if="connected">live</template>
|
||||||
|
<template v-else-if="usePolling">polling (5s)</template>
|
||||||
|
<template v-else>reconnecting</template>
|
||||||
<span v-if="!connected && socketError" class="text-amber-300">· {{ socketError }}</span>
|
<span v-if="!connected && socketError" class="text-amber-300">· {{ socketError }}</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+6
-1
@@ -58,7 +58,12 @@ export function openSocket({ onMessage, onOpen, onClose, onError }) {
|
|||||||
onError?.(event.code, event.reason)
|
onError?.(event.code, event.reason)
|
||||||
schedule()
|
schedule()
|
||||||
}
|
}
|
||||||
socket.onerror = () => socket.close()
|
socket.onerror = (event) => {
|
||||||
|
// The browser hides details here; surface what it does give us.
|
||||||
|
const detail = event?.message || 'connection error'
|
||||||
|
onError?.(0, detail)
|
||||||
|
socket.close()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
connect()
|
connect()
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user