致电另一个关于主题发射的改造电话 [英] Call another Retrofit call on Subject emission

查看:82
本文介绍了致电另一个关于主题发射的改造电话的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下课程:

public class SessionStore {
    Subject<Session, Session> subject;

    public SessionStore() {
       subject = new SerializedSubject<>(BehaviorSubject.create(new Session());
    }

    public void set(Session session) {
        subject.onNext(session);
    }

    public Observable<UserSession> observe() {
        return subject.distinctUntilChanged();
    }
}

在活动中,我观察会话并针对每个更改执行网络操作:

In activity I observe the session and perform network operation on each change:

private Subscription init() {
    return sessionStore
            .observe()
            .flatMap(new Func1<Session, Observable<Object>>() {
                @Override
                public Observable<Object> call(Session session) {
                    return (session.isValid() 
                       ? retrofitService.getThingForValid()
                       : retrofitService.getThingForInalid())
                       .subscribeOn(Schedulers.io());
                }
            })
            .subscribe(...);
}

现在我有一个Okhttp请求拦截器,其中当网络响应不是200码时,我将会话实例从有效设置为无效.

Now I have an Okhttp request interceptor, in which I set the session instance from valid to invalid when network response is non 200 code.

会发生这种情况:

  1. 在初始订阅会话存储时,执行getThingForValid(),但失败.
  2. OkHttp拦截失败并设置新会话.
  3. 会话存储发出一个新的,现在无效的会话.
  4. 新发射执行getThingForInvalid()方法.
  1. On initial subscription to session store the getThingForValid() is executed, and fails.
  2. OkHttp intercepts the fail and sets new session.
  3. Session store emits a new, now invalid session.
  4. The new emission executes a getThingForInvalid() method.

重要的是要知道此执行发生在上一个Retrofit调用的中间.这是因为OkHttp客户端由Retrofit包装,并且所有拦截器在Retrofit返回之前都已执行.

What is important to know is that this execution happens in the middle of the previous Retrofit call. This is because OkHttp client is wrapped by Retrofit and all interceptors are executed before Retrofit returns.

记住这一点,您意识到第二个调用已经由Retrofit执行和处理,而第一个调用尚未完成.

Having this in mind, you realize that the second call is being executed and processed by Retrofit already, while the first one hasn't finished yet.

  1. 在第一个调用结束时,由于响应不是200代码,因此它抛出HttpException.
  2. xception杀死了rx流,并因此杀死了第二个调用.

我试图忽略流中的此异常,但是第二个调用还是被Retrofit取消了.

I have tried to ignore this exception in stream but the second call is cancelled by Retrofit anyways.

请问您有什么想法可以使我的概念发挥作用吗?

Do you have any ideas how to make my concept work please?

推荐答案

如果在令牌到期的情况下获得响应代码401: 您需要将Authenticator添加到OkHttpClient.Builder

if you get response code 401 in case of token expiration: you need to add Authenticator in to OkHttpClient.Builder

builder.authenticator(new Authenticator() {
            @Override
            public Request authenticate(Route route, Response response) throws IOException {
                final LoginResponse newLoginResponse = refreshTokenClient.refreshToken();
                //save new token locally, if needed
                return response
                        .request()
                        .newBuilder()
                        .removeHeader("Api-Auth-Token") // removing old header
                        .addHeader("Api-Auth-Token", newLoginResponse.getAuthToken())
                        .build();
            }
        });

其中

public interface RefreshTokenService {

   @PUT("/api/v1/tokens")
   LoginResponse refreshToken();

 }

但是请注意:此Authenticator每次在响应代码为401时都会运行.

But pay attention: this Authenticator will run each time when response code is 401.

这篇关于致电另一个关于主题发射的改造电话的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆