Notice
Recent Posts
Recent Comments
Link
투케이2K
669. (Android/Java) [Rx] repeatWhen 사용해 http 폴링 방식 요청 수행 실시 - http polling request 본문
Android
669. (Android/Java) [Rx] repeatWhen 사용해 http 폴링 방식 요청 수행 실시 - http polling request
투케이2K 2023. 10. 17. 07:58[개발 환경 설정]
개발 툴 : AndroidStudio
[소스 코드]
// ----------------------------------------------------------------------------------------------------------------
// [HTTP 폴링 요청 부분]
// ----------------------------------------------------------------------------------------------------------------
try {
/**
* // -----------------------------------------
* [요약 설명]
* // -----------------------------------------
* 1. 개발 환경 : 안드로이드 스튜디오
* // -----------------------------------------
* 2. Rx 관련 라이브러리 설치 (build.gradle) :
*
* implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
* implementation 'io.reactivex.rxjava3:rxkotlin:3.0.1'
* implementation 'io.reactivex.rxjava3:rxjava:3.0.7'
* // -----------------------------------------
* 3. Scheduler (스케줄러) 기본 개념
*
* Scheduler 는 반응형 프로그래밍에서 동시성을 관리하며, 스레드 관리를 제어하기 위한 subscribeOn , observeOn 메소드 가 있습니다
* Scheduler 관련 용어 설명 :
* - AndroidSchedulers.mainThread() : 안드로이드의 UI 스레드에서 동작
* - Schedulers.io() : 비동기 처리를 위해 사용하는 스케줄러 (API 호출 등 네트워크를 사용한 호출)
* - Schedulers.computation() : 이벤트 그룹에서 간단한 연산이나 콜백 처리를 위해 사용 (스레드 풀이 순환하면서 실행됨)
* - Schedulers.from(executor) : 특정 executor를 스케줄러로 사용
* - Schedulers.newThread() : 새로운 스레드를 만드는 스케줄러
* - Schedulers.trampoline() : 큐에 있는 일이 끝나면 이어서 현재 스레드에서 수행
* - HandlerScheduler.from(handler) : 특정 핸들러 handler 에 의존하여 동작
* // -----------------------------------------
* */
// [http 요청 폴링 카운트 지정]
final int[] count = {3};
// [URL 주소 선언]
String url = "https://jsonplaceholder.typicode.com/posts";
// [파라미터 생성]
Map <String, Object> params = new HashMap<>();
params.put("userId", 1);
params.put("id", 1);
// [http 요청 수행]
N_AsyncHttp.requestGetQueryStringHttp(A_Intro.this, "http 요청", url, null, params) // [http 요청]
// ------------------------------------------------------------
.repeatWhen(obj-> obj.delay(3000L, TimeUnit.MILLISECONDS)) // TODO [3000 == 3초 마다 폴링]
// ------------------------------------------------------------
.retry((retryCnt, e)->{ // TODO [retry : onError 발생 시 재요청 시도 : 지정 횟수 동안 재호출]
S_Log._E_("http :: retry", new String[]{ String.valueOf(retryCnt) });
return retryCnt < 3 ? true : false;
})
// ------------------------------------------------------------
.subscribeOn(AndroidSchedulers.mainThread()) // [Observable (생성자) 로직을 IO 스레드에서 실행 : 백그라운드]
.observeOn(Schedulers.io()) // [Observer (관찰자) 로직을 메인 스레드에서 실행]
.subscribe(new DisposableObserver<String>() { // TODO [DisposableObserver : dispose : 아이템 발행을 중단 지정 위함]
@Override
public void onNext(@NonNull String value) {
S_Log._W_("http :: onNext", new String[]{ "COUNT :: " + String.valueOf(count[0]), "VALUE :: " + String.valueOf(value) });
// [카운트 감소]
count[0] -= 1;
// [폴링 카운트 횟수 체크]
if (count[0] <= 0){
S_Log._E_("http :: onNext", new String[]{ "Polling Count End" });
dispose(); // TODO [아이템 발행을 중단 : 완료 처리]
}
}
@Override
public void onError(@NonNull Throwable e) {
S_Log._E_("http :: onError", new String[]{ String.valueOf(e.getMessage()) });
}
@Override
public void onComplete() {
}
});
}
catch (Exception e){
e.printStackTrace();
}
// ----------------------------------------------------------------------------------------------------------------
// [Observable :: http 통신 수행 부분]
// ----------------------------------------------------------------------------------------------------------------
public static Observable<String> requestGetQueryStringHttp(Context mContext, String tag, String url, Map header, Map params){
// [로직 처리 실시]
return Observable.create(subscriber -> {
try {
// ------------------------------------------------------
// TODO [URL 변수 선언 실시]
// ------------------------------------------------------
String urlData = String.valueOf(url);
// ------------------------------------------------------
// ------------------------------------------------------
// TODO [url 에 파라미터 추가 실시]
// ------------------------------------------------------
if (C_Util.mapNotNull(params) == true) { // [파라미터가 있는 경우]
if (urlData.endsWith("?") == false){
urlData = urlData + "?";
}
urlData = urlData + C_Util.mapToUrlEncodeQueryString(params);
}
// ------------------------------------------------------
// ------------------------------------------------------
// TODO [OK HTTP 객체 선언 실시]
// ------------------------------------------------------
//OkHttpClient client = new OkHttpClient();
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(TIME_OUT_SECOND, TimeUnit.SECONDS) // [커넥션 제한 시간]
//.readTimeout(10, TimeUnit.SECONDS)
//.writeTimeout(10, TimeUnit.SECONDS)
.retryOnConnectionFailure(false)
.build();
Request.Builder request = new Request.Builder();
request.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8;"); //TODO [헤더]
request.addHeader("Cache-Control", "no-cache"); //TODO [헤더]
if (C_Util.mapNotNull(header) == true){
Set set = header.keySet();
Iterator iterator = set.iterator();
while(iterator.hasNext()){
String key = (String) iterator.next();
request.addHeader(key, String.valueOf(header.get(key))); //TODO [헤더 추가]
}
}
HttpUrl.Builder httpBuilder = HttpUrl.get(URI.create(urlData)).newBuilder();
request.url(httpBuilder.build()); //TODO [httpBuilder 추가]
// ------------------------------------------------------
// ------------------------------------------------------
// TODO [요청 로그 출력 실시]
// ------------------------------------------------------
S_Log._F_(mContext, "requestGetQueryStringHttp :: OK HTTP 비동기 GET [요청] 실시", new String[] {
"TAG :: " + String.valueOf(tag),
"TYPE :: " + "GET >> REQUEST",
"URL :: " + String.valueOf(urlData),
"HEADER :: " + String.valueOf(header),
"PARAMS :: " + String.valueOf(params)
});
// ------------------------------------------------------
// ------------------------------------------------------
// TODO [비동기 처리 (enqueue 사용)]
// ------------------------------------------------------
String finalUrlData = urlData;
client.newCall(request.build()).enqueue(new Callback() {
// TODO [성공한 경우]
@Override
public void onResponse(Call call, Response response) throws IOException {
final String responseUrl = String.valueOf(finalUrlData);
final String responseHeader = String.valueOf(response.headers().toString());
final String responseCode = String.valueOf(response.code());
final String responseData = String.valueOf(response.body().string());
// ------------------------------------------------------
// [로그 출력]
// ------------------------------------------------------
S_Log._F_(mContext, "requestGetQueryStringHttp :: OK HTTP 비동기 GET [응답] 확인", new String[] {
"TAG :: " + String.valueOf(tag),
"TYPE :: " + "GET >> RESPONSE",
"CODE :: " + String.valueOf(responseCode),
"URL :: " + String.valueOf(responseUrl),
"HEADER :: " + String.valueOf(responseHeader),
"DATA :: " + String.valueOf(responseData)
});
// ------------------------------------------------------
// ------------------------------------------------------
// TODO [응답 코드 값 체크 및 리턴 데이터 반환]
// ------------------------------------------------------
try {
int statusCode = response.code();
if (statusCode >= 200 && statusCode < 300){ // TODO [정상 응답]
// TODO [결과 전송 실시]
subscriber.onNext(responseData);
subscriber.onComplete();
}
else { // TODO [에러 응답]
subscriber.onError(new Throwable("[ERROR] : : [requestGetQueryStringHttp] : " + C_ErrorCheck.getErrorHttpMsg(responseCode)));
}
}
catch (Exception e){
S_Log._printStackTrace_(mContext, S_FinalMsg.LOG_BUG_STATE, null, e);
subscriber.onError(new Throwable("[EXCEPTION] : [1] : [requestGetQueryStringHttp] : " + e.getMessage()));
}
// ------------------------------------------------------
}
//TODO [실패한 경우]
@Override
public void onFailure(Call call, IOException e) {
final String responseUrl = String.valueOf(finalUrlData);
final String responseError = String.valueOf(e.getMessage());
// ------------------------------------------------------
// [로그 출력]
// ------------------------------------------------------
S_Log._F_(mContext, "requestGetQueryStringHttp :: OK HTTP 비동기 GET [에러] 확인", new String[] {
"TAG :: " + String.valueOf(tag),
"TYPE :: " + "GET >> FAIL",
"URL :: " + String.valueOf(responseUrl),
"DATA :: " + String.valueOf(responseError)
});
// ------------------------------------------------------
// ------------------------------------------------------
// TODO [리턴 데이터 반환]
// ------------------------------------------------------
try {
subscriber.onError(new Throwable("[FAIL] : [requestGetQueryStringHttp] : " + responseError));
}
catch (Exception ex){
ex.printStackTrace();
}
// ------------------------------------------------------
}
});
} catch (final Exception e){
// ------------------------------------------------------
// [로그 출력]
// ------------------------------------------------------
S_Log._printStackTrace_(mContext, S_FinalMsg.LOG_BUG_STATE, new String[] {
"requestGetQueryStringHttp :: OK HTTP 비동기 GET [EXCEPTION] 확인",
"TAG :: " + String.valueOf(tag),
"TYPE :: " + "GET >> EXCEPTION",
"EXCEPTION :: " + String.valueOf(e.getMessage())
}, e);
// ------------------------------------------------------
// ------------------------------------------------------
// TODO [리턴 데이터 반환]
// ------------------------------------------------------
try {
subscriber.onError(new Throwable("[EXCEPTION] : [2] : [requestGetQueryStringHttp] : " + String.valueOf(e.getMessage())));
}
catch (Exception ex){
ex.printStackTrace();
}
// ------------------------------------------------------
}
});
}
[결과 출력]
W///===========//: ================================================
I/: [LOG :: CLASS PLACE :: com.example.javaproject.A_Intro$2.onNext(A_Intro.java:408)]
I/: ----------------------------------------------------
I/: [LOG :: NOW TIME :: 2023-10-16 15:45:14 월요일]
I/: ----------------------------------------------------
I/: [LOG :: DESCRIPTION :: http :: onNext]
I/: ----------------------------------------------------
I/: [LOG :: COUNT :: 3]
I/: ----------------------------------------------------
I/: [LOG :: VALUE :: [
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}
]]
W///===========//: ================================================
W///===========//: ================================================
I/: [LOG :: CLASS PLACE :: com.example.javaproject.A_Intro$2.onNext(A_Intro.java:408)]
I/: ----------------------------------------------------
I/: [LOG :: NOW TIME :: 2023-10-16 15:45:17 월요일]
I/: ----------------------------------------------------
I/: [LOG :: DESCRIPTION :: http :: onNext]
I/: ----------------------------------------------------
I/: [LOG :: COUNT :: 2]
I/: ----------------------------------------------------
I/: [LOG :: VALUE :: [
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}
]]
W///===========//: ================================================
W///===========//: ================================================
I/: [LOG :: CLASS PLACE :: com.example.javaproject.A_Intro$2.onNext(A_Intro.java:408)]
I/: ----------------------------------------------------
I/: [LOG :: NOW TIME :: 2023-10-16 15:45:21 월요일]
I/: ----------------------------------------------------
I/: [LOG :: DESCRIPTION :: http :: onNext]
I/: ----------------------------------------------------
I/: [LOG :: COUNT :: 1]
I/: ----------------------------------------------------
I/: [LOG :: VALUE :: [
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}
]]
W///===========//: ================================================
E///===========//: ================================================
I/: [LOG :: CLASS PLACE :: com.example.javaproject.A_Intro$2.onNext(A_Intro.java:415)]
I/: ----------------------------------------------------
I/: [LOG :: NOW TIME :: 2023-10-16 15:45:21 월요일]
I/: ----------------------------------------------------
I/: [LOG :: DESCRIPTION :: http :: onNext]
I/: ----------------------------------------------------
I/: [LOG :: Polling Count End]
E///===========//: ================================================
반응형
'Android' 카테고리의 다른 글
Comments