SignalR-Client-Swift: SignalR crashes when app is moved to background and hub connection is closed

I have such reconnect policy:

class RTReconnectPolicy: ReconnectPolicy {
    private var connect: () -> Void
    private var retryTimeout = 1

    public init(connect: @escaping () -> Void) {
        self.connect = connect
    }

    func nextAttemptInterval(retryContext: RetryContext) -> DispatchTimeInterval {
        if let error = retryContext.error as? SignalRError, error.statusCode == 401 {
            Logger.shared.log(error.localizedDescription, logLevel: .error)
            connect()
            return DispatchTimeInterval.seconds(30)
        }

        Logger.shared.log(retryContext.error.localizedDescription, logLevel: .error)

        return DispatchTimeInterval.seconds(calculateTimeout(failedAttemptsCount: retryContext.failedAttemptsCount))
    }

    func calculateTimeout(failedAttemptsCount: Int) -> Int {
        if retryTimeout < 32 {
            retryTimeout = failedAttemptsCount * 2
            return retryTimeout
        } else {
            retryTimeout = 32
            return retryTimeout
        }
    }
}

and my connection method

        refreshTokenUseCase.execute()
            .sink(receiveValue: { accessToken in
                if !accessToken.isEmpty {
                    self.connecting = true

                    self.connection = HubConnectionBuilder(url: url)
                        .withLogging(minLogLevel: rtLogLevel, logger: Logger.shared)
                        .withJSONHubProtocol()
                        .withAutoReconnect(reconnectPolicy: RTReconnectPolicy(connect: { self.connect() }))
                        .withPermittedTransportTypes(.webSockets)
                        .withHttpConnectionOptions(configureHttpOptions: { options in
                            // to authorize RealtimeBroker connections with Access Token `skipNegotiation` parameter has to be set to `false`
                            options.accessTokenProvider = { accessToken }
                            options.skipNegotiation = false
                        })
                        .build()
                    self.connection?.delegate = self

                    self.connection?.start()
                }
            })
            .store(in: &cancellables)

disconnect method

    public func disconnect() {
        Logger.shared.log("Disconnecting from Realtime server with address: \(url?.absoluteString ?? "--")", logLevel: .info, file: "\(#file)", function: "\(#function)")
        connection?.stop()
    }

App uses access token for securing hub connection (before I used access token this error did not happened (and then I used default .autoReconnect() method but when using it with token it caused to many reconnections failing.

Scenario:

App is in foreground it has AT (access token) to open web socket, then I push it to background or lock a device. Connection is then closed with .disconnect() method. When I unlock device I have report that app had crashed. and in crash log I see what’s on image below.

I log also SignalR Error - 8

image

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 15 (9 by maintainers)

Commits related to this issue

Most upvoted comments

We have the same issue, and my colleague found the bug, there is a double semaphore.wait, the one in the closure of resetKeepAlive, and the one in cleanupKeepAlive. So it comes to a freeze/crash. I try to fix it.