Я действительно новичок в RxJava, но я пытаюсь реализовать API с помощью Retrofit framework и RxJava. На стороне сервера есть служба авторизации, которая обрабатывает сеанс пользователя, и в случае некоторой задержки в действиях пользователя сервер прерывает свою сессию. После этого пользователь должен снова войти в систему, чтобы выполнить новый вызов API. Плохая вещь - сервер всегда возвращает HTTP-код 200, а для уведомления об истечении срока действия использует некоторый пользовательский ответ JSON с кодом срока действия, поэтому RxJava не запускает Exception во время операции onNext, потому что RxJava считает, что запрос был успешно принят.Принудительный повторный запрос запроса после пользовательских исключений API в RxJava
Вопрос: Как реализовать правильный поток для обработки пользовательских исключений API, таких как истечение и повторный запрос с запросом после какого-либо другого запроса (в моем случае relogin)?
Что-то вроде этого:
- приложения -> Логин()
- сервера -> {код: 0, ...}
- приложения -> getUsers()
- сервера -> {код: 0, ...}
- ------- 30 минут -------
- приложение -> getPicture()
- сервер -> {код: 99,. ..} // s ession истек, пользователь неавторизованный
- приложение -> Логин()
- сервер -> {код: 0, ...}
- приложение -> getPicture()
- сервер -> {код: 0,. ..}
Я думал о чем-то вроде этого, но без успеха:
Observable.create(new Observable.OnSubscribe<BackendResponse<String>>() {
@Override
public void call(Subscriber<? super Response<String>> subscriber) {
try {
Response<String> response;
subscriber.onNext(response = getInterface().getUsers());
if (response != null) {
response.checkData(); // throws ServerException in case of code != 0
}
subscriber.onCompleted();
} catch (Exception e) {
subscriber.onError(e);
}
}
}).subscribeOn(Schedulers.io()).retryWhen(new RetryWithSessionRefresh(new SessionService())).subscribe();
и RetryWithSessionRefresh является:
public class RetryWithSessionRefresh implements
Func1<Observable<? extends Notification<?>>, Observable<?>> {
private final SessionService sessionSerivce;
public RetryWithSessionRefresh(SessionService sessionSerivce) {
this.sessionSerivce = sessionSerivce;
}
@Override
public Observable<?> call(Observable<? extends Notification<?>> attempts) {
return attempts
.flatMap(new Func1<Notification<?>, Observable<?>>() {
@Override
public Observable<?> call(final Notification notification) {
final Throwable throwable = notification.getThrowable();
if (throwable instanceof ServerException) {
final ServerException backendException = (ServerException) throwable;
if (backendException.getBackendErrorCode() == Response.AUTHORIZATION_FAILED) {
return sessionSerivce
.observeSessionToken()
.doOnNext(new Action1<TokenCallback>() {
@Override
public void call(TokenCallback token) {
if (token != null) {
DataHolder.getInstance().setAuthToken(token.getToken());
}
}
})
.doOnError(new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
DataHolder.getInstance().setAuthToken("");
}
});
}
}
return Observable.error(notification.getThrowable());
}
});
}