dotnet / AspNetCore.Docs

Documentation for ASP.NET Core
https://docs.microsoft.com/aspnet/core
Creative Commons Attribution 4.0 International
12.65k stars 25.28k forks source link

Retry Connection logic for SignalR #32993

Open Manojkumar226 opened 4 months ago

Manojkumar226 commented 4 months ago

( See Brennan's comment in discussion below for the suggestion related to docs. )

Is there an existing issue for this?

Describe the bug

Some browser tab will go into sleep if it is not active (ex: google chrome). In that case how can we ensure the connection with signalR automatically when the browser tab is get back to active.

We are looking for a way to make the signalR connection to be established all the time inorder to show the live updates in our react application.

The below is the signalr intialization and reconnection logic that we have adpoted:

const useSignalRInitialization = (): HookReturnTypes => {
  const getNewAccessTokenAPI = useGetSignalRAccessToken()

  const signalRConnection = new HubConnectionBuilder()
    .withUrl(getSignalRConnectionUrl() , {
      accessTokenFactory: () => getSignalRAccessToken() ,
      skipNegotiation: true,
      transport: HttpTransportType.WebSockets
    })
    .configureLogging(LogLevel.Information)
    .build()

  const isTokenExpired = () => {
    return new Date().getTime() > new Date(<current Access token expirytime>).getTime()
  }

  const refreshAccessToken = async (): Promise<void> => {
    if (isTokenExpired()) {
      await getNewAccessTokenAPI.triggerAPI({
        deviceId: getDeviceId()
      })
      startConnection()
    }
  }

  const startConnection = async (): Promise<void> => {
    if (signalRConnection.state === HubConnectionState.Disconnected) {
      try {
        await signalRConnection.start()
        console.log('Connected to SignalR')
      } catch (err) {
        console.error('Error connecting to SignalR:', err)
        refreshAccessToken()
      }
    }
  }

  useEffect(() => {
    startConnection()

    signalRConnection.onclose(async () => {
      console.log('trying to reconnect to signalR server')

      refreshAccessToken()
    })

    return () => {
      clearInterval(interval)
      signalRConnection.stop()
    }
  }, [])

  return {
    signalRHubConnection: signalRConnection
  }
}

Expected Behavior

Any suggestions or improvements in the reconnection logic of the signalR to ensure the connection should be established all the time. And also provide us some insights to tackle the below case:

Some browser tab will go into sleep if it is not active (ex: google chrome). In that case how can we ensure the connection with signalR automatically when the browser tab is get back to active.

Steps To Reproduce

No response

Exceptions (if any)

No response

.NET Version

No response

Anything else?

No response

BrennanConroy commented 4 months ago

You can use the freeze and resume events to write reconnection logic for this. https://wicg.github.io/page-lifecycle/spec.html#example

Might be useful to mention in the docs about tab freezing https://learn.microsoft.com/en-us/aspnet/core/signalr/javascript-client?view=aspnetcore-8.0&tabs=visual-studio#bsleep