I am building a chat service and I want to handle the cases when the subscription(websocket) connection is disconnected. Apollo client is configured like bellow. I removed unnecessary code like cache, authLink etc.
How do I do this with react, apollo client? If its disconnected, I would like to show that to the chat page and when the user reconnects, I would like to fetch all the missed chat messages. This is why I need to know the disconnect, connect events
Below are the relevant packages used in this app:
"@apollo/client": "^3.3.7",
"subscriptions-transport-ws": "^0.9.18",
"react": "^17.0.1"
const httpLink = new BatchHttpLink({ uri: config.API_URL })
const wsLink = new WebSocketLink({
uri: config.WS_URL,
options: {
reconnect: true,
connectionParams:{
authToken: accessToken,
},
},
})
const splitLink = split(
({ query }) => {
const definition = getMainDefinition(query)
return definition.kind === 'OperationDefinition' && definition.operation === 'subscription'
},
wsLink,
httpLink
)
const client = new ApolloClient({
cache,
link: from([new SentryLink(), authLink, errorLink, splitLink]),
})
I finally found the solution. It turns out that you can declare a SubscriptionClient
first and then insert this into WebSocketLink
, rather than declare with WebSocketLink
directly.
With SubscriptionClient, you can listen to the necessary events, whereas with WebsocketLink
its not really possible(or very limited).
Unfortunately, no where in Apollo docs, mentions SubscriptionClient
or ways of handling connection issues.
import { WebSocketLink } from '@apollo/client/link/ws'
import { SubscriptionClient } from 'subscriptions-transport-ws' // <- import this
const wsClient = new SubscriptionClient(config.WS_URL, {
reconnect: true,
connectionParams: {
authToken: accessToken,
},
})
const wsLink = new WebSocketLink(wsClient)
By doing so, now you can listen to connection events with wsClient
wsClient.onConnected(() => console.log("websocket connected!!"))
wsClient.onDisconnected(() => console.log("websocket disconnected!!"))
wsClient.onReconnected(() => console.log("websocket reconnected!!"))
There are more events you can listen to. But these events are sufficient to implement fetching missed chat messages.
With these events, after initial connection, you can store the disconnectTimestamp
on disconnect event. When you receive onReconnected
event, you can simply fetch chat messages that were created after the disconnectTimestamp