Fix: sometimes the socket does not reconnect on mobile
This commit is contained in:
parent
5dec543169
commit
e1297f3799
1 changed files with 48 additions and 1 deletions
|
|
@ -1,4 +1,6 @@
|
||||||
import { io, type Socket as IOSocket, type SocketOptions, type ManagerOptions } from "socket.io-client"
|
import { io, type Socket as IOSocket, type SocketOptions, type ManagerOptions } from "socket.io-client"
|
||||||
|
import { ref, readonly } from 'vue'
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
import type { ConfigState } from "~/types/config";
|
import type { ConfigState } from "~/types/config";
|
||||||
import type { StoreItem } from "~/types/store";
|
import type { StoreItem } from "~/types/store";
|
||||||
|
|
||||||
|
|
@ -15,6 +17,8 @@ export const useSocketStore = defineStore('socket', () => {
|
||||||
const connectionStatus = ref<connectionStatus>('disconnected')
|
const connectionStatus = ref<connectionStatus>('disconnected')
|
||||||
const error = ref<string | null>(null)
|
const error = ref<string | null>(null)
|
||||||
const error_count = ref<number>(0)
|
const error_count = ref<number>(0)
|
||||||
|
const wasHidden = ref<boolean>(false)
|
||||||
|
const reconnectTimeout = ref<NodeJS.Timeout | null>(null)
|
||||||
|
|
||||||
const emit = (event: string, data?: any): any => socket.value?.emit(event, data)
|
const emit = (event: string, data?: any): any => socket.value?.emit(event, data)
|
||||||
const on = (event: string | string[], callback: (...args: any[]) => void, withEvent: boolean = false) => {
|
const on = (event: string | string[], callback: (...args: any[]) => void, withEvent: boolean = false) => {
|
||||||
|
|
@ -33,6 +37,46 @@ export const useSocketStore = defineStore('socket', () => {
|
||||||
|
|
||||||
const getSessionId = (): string | null => socket.value?.id || null
|
const getSessionId = (): string | null => socket.value?.id || null
|
||||||
|
|
||||||
|
const handleVisibilityChange = () => {
|
||||||
|
if (document.hidden) {
|
||||||
|
wasHidden.value = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true === wasHidden.value && false === isConnected.value) {
|
||||||
|
if (null !== reconnectTimeout.value) {
|
||||||
|
clearTimeout(reconnectTimeout.value)
|
||||||
|
reconnectTimeout.value = null
|
||||||
|
}
|
||||||
|
|
||||||
|
reconnectTimeout.value = setTimeout(() => {
|
||||||
|
if (false === isConnected.value) {
|
||||||
|
console.debug('[SocketStore] Page visible after background, reconnecting...')
|
||||||
|
reconnect()
|
||||||
|
}
|
||||||
|
reconnectTimeout.value = null
|
||||||
|
}, 100)
|
||||||
|
}
|
||||||
|
|
||||||
|
wasHidden.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
const setupVisibilityListener = () => {
|
||||||
|
if (typeof document !== 'undefined') {
|
||||||
|
document.addEventListener('visibilitychange', handleVisibilityChange)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const cleanupVisibilityListener = () => {
|
||||||
|
if (typeof document !== 'undefined') {
|
||||||
|
document.removeEventListener('visibilitychange', handleVisibilityChange)
|
||||||
|
}
|
||||||
|
if (null !== reconnectTimeout.value) {
|
||||||
|
clearTimeout(reconnectTimeout.value)
|
||||||
|
reconnectTimeout.value = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const reconnect = () => {
|
const reconnect = () => {
|
||||||
if (true === isConnected.value) {
|
if (true === isConnected.value) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -49,6 +93,7 @@ export const useSocketStore = defineStore('socket', () => {
|
||||||
socket.value = null;
|
socket.value = null;
|
||||||
isConnected.value = false;
|
isConnected.value = false;
|
||||||
connectionStatus.value = 'disconnected';
|
connectionStatus.value = 'disconnected';
|
||||||
|
cleanupVisibilityListener();
|
||||||
}
|
}
|
||||||
|
|
||||||
const connect = () => {
|
const connect = () => {
|
||||||
|
|
@ -234,6 +279,8 @@ export const useSocketStore = defineStore('socket', () => {
|
||||||
|
|
||||||
on('presets_update', (data: string) => config.update('presets', JSON.parse(data).data || []));
|
on('presets_update', (data: string) => config.update('presets', JSON.parse(data).data || []));
|
||||||
on('dlfields_update', (data: string) => config.update('dl_fields', JSON.parse(data).data || []));
|
on('dlfields_update', (data: string) => config.update('dl_fields', JSON.parse(data).data || []));
|
||||||
|
|
||||||
|
setupVisibilityListener();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (false === isConnected.value) {
|
if (false === isConnected.value) {
|
||||||
|
|
@ -243,7 +290,7 @@ export const useSocketStore = defineStore('socket', () => {
|
||||||
return {
|
return {
|
||||||
connect, reconnect, disconnect,
|
connect, reconnect, disconnect,
|
||||||
on, off, emit,
|
on, off, emit,
|
||||||
socket, isConnected,
|
isConnected,
|
||||||
getSessionId,
|
getSessionId,
|
||||||
connectionStatus: readonly(connectionStatus) as Readonly<Ref<connectionStatus>>,
|
connectionStatus: readonly(connectionStatus) as Readonly<Ref<connectionStatus>>,
|
||||||
error: readonly(error) as Readonly<Ref<string | null>>,
|
error: readonly(error) as Readonly<Ref<string | null>>,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue