如何使用RxJava进行同步调用

时间:2018-11-27 15:44:34

标签: authentication kotlin synchronization rx-java

我需要进行同步调用以重新认证用户并获取新令牌,但是我还没有找到一种可行的方法。下面的代码将阻塞线程,并且永远不会解除阻塞,即。我有无限循环

class ApolloAuthenticator(private val authenticated: Boolean) : Authenticator {

  @Throws(IOException::class)
  override fun authenticate(route: Route, response: Response): Request? {
    // Refresh your access_token using a synchronous api request

    if (response.request().header(HEADER_KEY_APOLLO_AUTHORIZATION) != null) {
      return null  //if you've tried to authorize and failed, give up
    }

    synchronized(this) {

      refreshTokenSync() // This is blocked and never unblocked
      val newToken = getApolloTokenFromSharedPreference()
      return response.request().newBuilder()
        .header(HEADER_KEY_APOLLO_AUTHORIZATION, newToken)
        .build()
    }

    private fun refreshTokenSync(): EmptyResult {
      //Refresh token, synchronously
      val repository = Injection.provideSignInRepository()
      return repository
        .signInGraphQL()
        .toBlocking()
        .first()

   }

   fun signInGraphQL() : Observable<EmptyResult> =
sharedPreferencesDataSource.identifier
  .flatMap { result -> graphqlAuthenticationDataSource.getAuth(result) }
  .flatMap { result -> sharedPreferencesDataSource.saveApolloToken(result) }
  .onErrorReturn { EmptyResult() }

}

----------使用它

 val apollAuthenticator = ApolloAuthenticator(authenticated)
    val okHttpBuilder =
      OkHttpClient.Builder()
        .authenticator(apollAuthenticator)

1 个答案:

答案 0 :(得分:0)

我还没有找到使用RxJava进行同步调用的方法,但是我可以使用kotlin coutorine runBlocking来实现,它将阻塞线程直到请求完成:

synchronized(this) {
    runBlocking {
        val subscription = ApolloReauthenticator.signInGraphQl() // await until it's finished
          subscription.unsubscribe()
     }
}


fun signInGraphQl(): Subscription {
   return repository.refreshToken()
     .subscribe(
       { Observable.just(EmptyResult()) },
       { Observable.just(EmptyResult()) }
     )
 }