Recovery
How the library retries a lost connection, when errors reach you, and when to refetch.
A lost connection has two retry layers. Both run without your code.
Two retry layers
SignalR auto-reconnect keeps the same connection object. It uses the delays of the reconnect option (default 0, 2, 10, and 30 s). It reads the token again on each attempt. The connection ID stays the same only with stateful reconnect. Otherwise the server gives a new connection ID.
Library rebuild creates a new connection. The delay before attempt n is min(2500 × n, 30000) ms. There is no attempt limit while the hub is wanted. The rebuild stops only on a non-retriable error (400, 401, 403, or 404). It runs after auto-reconnect gives up, and always when reconnect is false.
reconnect: false turns off only the first layer. The library still rebuilds a lost connection. To stop all retries, set enabled to false, clear baseUrl, or stop the session.
onError
onError(hub, error, info) is an option of app.use(signalR, options). info.source is "connection" for connect, negotiate, build, protocol, and close errors, and for a stop() that rejects. It is "callback" for an error that your own code throws: an event handler, a reconnect callback, or onStatusChange.
onError fires in these cases:
- A connect attempt fails, or a connection closes and the library starts a rebuild. Only the first failed attempt of an outage fires. The count starts again after a successful connect.
- Auto-reconnect gives up, with the error
Reconnect retries exhausted. With the default delays, this is about 42 s after the drop. - SignalR closes the connection with no error and does not start auto-reconnect. The error is
The server or a proxy closed the connection. - A non-retriable error stops the hub. It fires once.
A drop that auto-reconnect fixes does not fire onError. To alert the user about a drop, watch for the status "reconnecting". Check info.source === "connection" before you show a message that the connection failed.
Without onError, the library drops errors silently.
Reconnect callbacks
useOnReconnected registers a function that runs after a hub recovers. Use it to refetch state that changed while the client was offline:
<script setup lang="ts">
import { onMounted, ref } from "vue";
import { useOnReconnected, useSignalRInvoke } from "./client";
import { ignoreAbort } from "./ignore-abort";
import type { ChatMessage } from "./contract";
const props = defineProps<{ roomId: string }>();
const history = ref<ChatMessage[]>([]);
const getHistory = useSignalRInvoke("/hubs/rooms", "GetHistory");
async function load() {
try {
history.value = await getHistory(props.roomId);
} catch (e) {
ignoreAbort(e);
}
}
onMounted(load);
useOnReconnected("/hubs/rooms", load);
</script>
<template>
<ul>
<li v-for="(message, index) in history" :key="index">{{ message.text }}</li>
</ul>
</template>A reconnect callback runs after each recovery of a hub that was connected before. This includes:
- an automatic reconnect of SignalR,
- a library rebuild after a lost connection,
- a rebuild after a change of
connectionKey,baseUrl, orenabled, when the hub was connected before.
It does not run on the first connect, after the session stops and starts again, or when a lazy hub stops and starts again.
The server forgets the groups of a closed connection. Join your groups again in a reconnect callback, or join in OnConnectedAsync on the server.