All checks were successful
Build and Deploy Nuxt / build (push) Successful in 42s
69 lines
1.4 KiB
TypeScript
69 lines
1.4 KiB
TypeScript
import { ref, onUnmounted } from 'vue'
|
|
import { io } from 'socket.io-client'
|
|
|
|
function normalizeUrl(url: string): string {
|
|
return url.replace(/\/+$/, '')
|
|
}
|
|
|
|
export default function useSocket() {
|
|
const config = useRuntimeConfig()
|
|
const apiBaseUrl = normalizeUrl(config.public.apiBaseUrl)
|
|
|
|
const socket = ref(null)
|
|
const isConnected = ref(false)
|
|
|
|
function initSocket() {
|
|
if (socket.value) return
|
|
|
|
const s = io(apiBaseUrl, {
|
|
path: '/api/socket.io',
|
|
transports: ['websocket', 'polling'],
|
|
reconnection: true,
|
|
reconnectionAttempts: 10,
|
|
reconnectionDelay: 1000,
|
|
})
|
|
|
|
s.on('connect', () => {
|
|
console.log('[socket.io] connected')
|
|
isConnected.value = true
|
|
})
|
|
|
|
s.on('disconnect', () => {
|
|
console.log('[socket.io] disconnected')
|
|
isConnected.value = false
|
|
})
|
|
|
|
s.on('connect_error', (err) => {
|
|
console.error('[socket.io] connection error:', err.message)
|
|
isConnected.value = false
|
|
})
|
|
|
|
socket.value = s
|
|
}
|
|
|
|
function onGridCellPaint(callback) {
|
|
if (!socket.value) initSocket()
|
|
socket.value.on('grid-cell-paint', callback)
|
|
}
|
|
|
|
function removeGridCellPaintListener() {
|
|
if (socket.value) {
|
|
socket.value.off('grid-cell-paint')
|
|
}
|
|
}
|
|
|
|
onUnmounted(() => {
|
|
if (socket.value) {
|
|
socket.value.disconnect()
|
|
socket.value = null
|
|
}
|
|
})
|
|
|
|
return {
|
|
isConnected,
|
|
initSocket,
|
|
onGridCellPaint,
|
|
removeGridCellPaintListener,
|
|
}
|
|
}
|