useRealtimeConnection
useRealtimeConnection
Monitor and control the WebSocket connection status. Use this composable to show connection indicators, handle reconnection logic, or manually control the connection.
Usage
<script setup>
const { connected, status } = useRealtimeConnection()
</script>
<template>
<span :class="connected ? 'text-green-500' : 'text-red-500'">
{{ status }}
</span>
</template>
Type Signature
function useRealtimeConnection(
options?: UseRealtimeConnectionOptions
): UseRealtimeConnectionReturn
Options
interface UseRealtimeConnectionOptions {
onConnected?: () => void
onDisconnected?: (reason: string) => void
onReconnecting?: (attempt: number) => void
onReconnected?: (attempt: number) => void
onReconnectFailed?: () => void
onError?: (error: Error) => void
}
Event Callbacks
| Callback | Description |
|---|---|
onConnected | Called when connection is established |
onDisconnected | Called when disconnected, with disconnect reason |
onReconnecting | Called on each reconnection attempt, with attempt number |
onReconnected | Called after successful reconnection, with total attempts |
onReconnectFailed | Called when all reconnection attempts have failed |
onError | Called on connection errors |
Return Value
interface UseRealtimeConnectionReturn {
// Reactive state
connected: Readonly<Ref<boolean>>
status: Readonly<Ref<ConnectionStatus>>
attempt: Readonly<Ref<number | undefined>>
// Methods
connect: () => void
disconnect: () => void
// Raw socket
socket: Socket
}
type ConnectionStatus = 'connected' | 'disconnected' | 'connecting' | 'reconnecting'
connected
A readonly boolean ref indicating if the socket is currently connected:
const { connected } = useRealtimeConnection()
watchEffect(() => {
if (connected.value) {
console.log('Online')
} else {
console.log('Offline')
}
})
status
A readonly ref with the current connection status:
| Status | Description |
|---|---|
connected | Successfully connected to the server |
disconnected | Not connected to the server |
connecting | Initial connection in progress |
reconnecting | Attempting to reconnect after disconnect |
const { status } = useRealtimeConnection()
const statusMessage = computed(() => {
switch (status.value) {
case 'connected': return 'Online'
case 'disconnected': return 'Offline'
case 'connecting': return 'Connecting...'
case 'reconnecting': return 'Reconnecting...'
}
})
attempt
A readonly ref with the current reconnection attempt number. undefined when not reconnecting:
const { status, attempt } = useRealtimeConnection()
// Only defined during reconnection
if (status.value === 'reconnecting') {
console.log(`Reconnection attempt ${attempt.value}`)
}
connect()
Manually initiate a connection:
const { connect, disconnect } = useRealtimeConnection()
// Disconnect
disconnect()
// Later, reconnect
connect()
disconnect()
Manually disconnect from the server:
const { disconnect } = useRealtimeConnection()
function goOffline() {
disconnect()
}
socket
Access the raw Socket.IO socket instance for advanced usage:
const { socket } = useRealtimeConnection()
// Listen to custom events
socket.on('custom-event', (data) => {
console.log('Custom event:', data)
})
// Emit custom events
socket.emit('custom-event', { foo: 'bar' })
useRealtimeState and useRealtimeEvents for most use cases.Examples
Connection Status Badge
Show a visual indicator of the connection status:
<script setup>
const { connected, status, attempt } = useRealtimeConnection()
const statusConfig = computed(() => {
switch (status.value) {
case 'connected':
return { color: 'success', icon: 'i-lucide-wifi', text: 'Connected' }
case 'disconnected':
return { color: 'error', icon: 'i-lucide-wifi-off', text: 'Disconnected' }
case 'connecting':
return { color: 'warning', icon: 'i-lucide-loader', text: 'Connecting' }
case 'reconnecting':
return { color: 'warning', icon: 'i-lucide-loader', text: `Reconnecting (${attempt.value})` }
}
})
</script>
<template>
<UBadge :color="statusConfig.color">
<UIcon :name="statusConfig.icon" class="mr-1" />
{{ statusConfig.text }}
</UBadge>
</template>
Connection Events Logging
Log all connection events for debugging:
<script setup>
const logs = ref<string[]>([])
function log(message: string) {
logs.value.unshift(`[${new Date().toLocaleTimeString()}] ${message}`)
}
const { status } = useRealtimeConnection({
onConnected: () => log('Connected to server'),
onDisconnected: (reason) => log(`Disconnected: ${reason}`),
onReconnecting: (attempt) => log(`Reconnecting, attempt ${attempt}`),
onReconnected: (attempt) => log(`Reconnected after ${attempt} attempts`),
onReconnectFailed: () => log('Reconnection failed'),
onError: (error) => log(`Error: ${error.message}`),
})
</script>
<template>
<div>
<h3>Connection Logs</h3>
<ul>
<li v-for="(entry, i) in logs" :key="i">{{ entry }}</li>
</ul>
</div>
</template>
Offline Banner
Show a banner when disconnected:
<script setup>
const { connected, status } = useRealtimeConnection()
</script>
<template>
<Transition name="slide">
<div
v-if="!connected"
class="fixed top-0 inset-x-0 bg-yellow-500 text-white p-2 text-center"
>
<span v-if="status === 'reconnecting'">
Reconnecting to server...
</span>
<span v-else>
You are offline. Some features may not work.
</span>
</div>
</Transition>
</template>
<style scoped>
.slide-enter-active,
.slide-leave-active {
transition: transform 0.3s ease;
}
.slide-enter-from,
.slide-leave-to {
transform: translateY(-100%);
}
</style>
Manual Connection Control
Let users manually control their connection:
<script setup>
const { connected, connect, disconnect } = useRealtimeConnection()
</script>
<template>
<div>
<p>Status: {{ connected ? 'Online' : 'Offline' }}</p>
<button
v-if="connected"
@click="disconnect"
class="bg-red-500 text-white px-4 py-2 rounded"
>
Go Offline
</button>
<button
v-else
@click="connect"
class="bg-green-500 text-white px-4 py-2 rounded"
>
Reconnect
</button>
</div>
</template>
Disable Features When Offline
Conditionally disable features based on connection status:
<script setup>
const { connected } = useRealtimeConnection()
const counter = useRealtimeState('counter', 0)
</script>
<template>
<div>
<p>Counter: {{ counter }}</p>
<button
:disabled="!connected"
:class="{ 'opacity-50 cursor-not-allowed': !connected }"
@click="counter++"
>
Increment
</button>
<p v-if="!connected" class="text-sm text-gray-500">
Connect to modify the counter
</p>
</div>
</template>
Disconnect Reasons
The onDisconnected callback receives a reason string. Common reasons include:
| Reason | Description |
|---|---|
io server disconnect | Server forcefully disconnected the client |
io client disconnect | Client called socket.disconnect() |
ping timeout | Server didn't respond to ping within timeout |
transport close | Connection was closed (network issue, server restart) |
transport error | Connection encountered an error |
useRealtimeConnection({
onDisconnected: (reason) => {
if (reason === 'io server disconnect') {
// Server kicked us out, may need to re-authenticate
console.log('Server disconnected us')
} else if (reason === 'io client disconnect') {
// We disconnected intentionally
console.log('We disconnected')
} else {
// Network issue, will auto-reconnect
console.log('Connection lost, reconnecting...')
}
},
})