86 lines
2.0 KiB
TypeScript
86 lines
2.0 KiB
TypeScript
import {defineStore} from 'pinia';
|
|
import {useAppStore} from "@/stores/app.ts";
|
|
import {useAuthStore} from "@/stores/auth.ts";
|
|
|
|
type GatewayStatus = 'disconnected' | 'connecting' | 'connected' | 'error'
|
|
|
|
export const useGatewayStore = defineStore('gateway', {
|
|
state: () => ({
|
|
socket: null as WebSocket | null,
|
|
status: 'disconnected' as GatewayStatus,
|
|
reconnectAttempts: 0,
|
|
}),
|
|
|
|
actions: {
|
|
async connect() {
|
|
if (this.socket && this.status === 'connected') {
|
|
return
|
|
}
|
|
|
|
const appStore = useAppStore()
|
|
const authStore = useAuthStore()
|
|
|
|
|
|
this.status = 'connecting'
|
|
const token = authStore.token
|
|
if (!token) {
|
|
this.status = 'error'
|
|
return
|
|
}
|
|
|
|
const apiUri = appStore.baseurl ? new URL(appStore.baseurl) : new URL(window.location.href)
|
|
const wsProtocol = apiUri.protocol === 'https:' ? 'wss:' : 'ws:'
|
|
|
|
const wsUrl = `${wsProtocol}//${apiUri.host}/ws/gateway?token=${encodeURIComponent(token)}`
|
|
const socket = new WebSocket(wsUrl)
|
|
|
|
socket.onopen = () => {
|
|
this.status = 'connected'
|
|
this.reconnectAttempts = 0
|
|
}
|
|
|
|
socket.onclose = () => {
|
|
this.status = 'disconnected'
|
|
this.socket = null
|
|
this.scheduleReconnect()
|
|
}
|
|
|
|
socket.onerror = () => {
|
|
this.status = 'error'
|
|
}
|
|
|
|
socket.onmessage = event => {
|
|
this.handleMessage(event.data)
|
|
}
|
|
|
|
this.socket = socket
|
|
},
|
|
|
|
async disconnect() {
|
|
this.socket?.close()
|
|
this.socket = null
|
|
this.status = 'disconnected'
|
|
},
|
|
|
|
async send(payload: object) {
|
|
if (!this.socket || this.status !== 'connected') {
|
|
console.warn('WebSocket is not connected')
|
|
return
|
|
}
|
|
|
|
this.socket.send(JSON.stringify(payload))
|
|
},
|
|
|
|
async handleMessage(rawData: string) {
|
|
},
|
|
|
|
async scheduleReconnect() {
|
|
const delay = Math.min(1000 * 2 ** this.reconnectAttempts, 30000)
|
|
this.reconnectAttempts += 1
|
|
|
|
window.setTimeout(() => {
|
|
this.connect()
|
|
}, delay)
|
|
},
|
|
}
|
|
}); |