투케이2K

865. (Android/Java) [Okhttp 4.9.0] WebSocket 웹소켓 통신 연결 및 실시간 메시지 수신 상태 확인 본문

Android

865. (Android/Java) [Okhttp 4.9.0] WebSocket 웹소켓 통신 연결 및 실시간 메시지 수신 상태 확인

투케이2K 2024. 9. 5. 17:43

[개발 환경 설정]

개발 툴 : AndroidStudio

개발 언어 : Java / Kotlin

 

[소스 코드]

 

    // ------------------------------------------------------------------------------------------
    // TODO [소켓 생성 실시]
    // -----------------------------------------------------------------------------------------
    // TODO [호출 방법 소스 코드]
    // -----------------------------------------------------------------------------------------
    /*
    try {

        // [URL 주소 선언]
        String url = "wss://javascript.info/article/websocket/demo/hello";

        // [파라미터 생성]
        Map<String, Object> headers = new HashMap<>();
        //headers.put("x-api-key", "sample_key"); // [key 인증시 사용]

        // [http 요청 수행]
        c_socket.startWebsocket("WebSocket 통신 요청", url, headers) // [http 요청]
                .subscribeOn(AndroidSchedulers.mainThread()) // [Observable (생성자) 로직을 IO 스레드에서 실행 : 백그라운드]
                .observeOn(Schedulers.io()) // [Observer (관찰자) 로직을 메인 스레드에서 실행]
                .subscribe(new Observer<String>() { // [Observable.create 타입 지정]
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                    }

                    @Override
                    public void onNext(@NonNull String value) {

                    }

                    @Override
                    public void onError(@NonNull Throwable e) {

                    }

                    @Override
                    public void onComplete() {
                    }
                });
    }
    catch (Exception e){
        S_Log._printStackTrace_(null, S_FinalData.LOG_BUG_STATE, null, e);
    }
    // */
    // -----------------------------------------------------------------------------------------

    public Observable<String> startWebsocket(String tag, String url, Map header){

        // [로직 처리 실시]
        return Observable.create(subscriber -> {

            try {

                if (mMainCtx != null){

                    // ------------------------------------------------------
                    // TODO [subscriber 전역 변수 지정]
                    // ------------------------------------------------------
                    this.webSocketSubscriber = subscriber;
                    // ------------------------------------------------------


                    // ------------------------------------------------------
                    // TODO [사전 방어 로직 : url 데이터 값 체크 실시]
                    // ------------------------------------------------------
                    if (C_Util.stringNotNull(url) == false){
                        try { this.webSocketSubscriber.onError(new Throwable("[FAIL] : [startWebsocket] : Input Url Is Null")); this.webSocketSubscriber.onComplete(); } catch (Exception ex){ ex.printStackTrace(); }
                        return;
                    }
                    // ------------------------------------------------------


                    // ------------------------------------------------------
                    // TODO [사전 방어 로직 : url 데이터 값 체크 실시]
                    // ------------------------------------------------------
                    if (String.valueOf(url).startsWith("ws://") == true || String.valueOf(url).startsWith("wss://") == true
                            || String.valueOf(url).startsWith("http://") == true || String.valueOf(url).startsWith("https://") == true){
                    }
                    else {
                        try { this.webSocketSubscriber.onError(new Throwable("[FAIL] : [startWebsocket] : Input Url Type Error")); this.webSocketSubscriber.onComplete(); } catch (Exception ex){ ex.printStackTrace(); }
                        return;
                    }
                    // ------------------------------------------------------



                    // ------------------------------------------------------
                    // TODO [URL 변수 선언 실시]
                    // ------------------------------------------------------
                    String urlData = String.valueOf(url);
                    // ------------------------------------------------------



                    // ------------------------------------------------------
                    // TODO [HTTP 통신 전문 로그 기록]
                    // ------------------------------------------------------
                    S_FileManager.appHttpLogSave(mMainCtx, "\n\n\n\n\n\n\n\n\n");
                    S_FileManager.appHttpLogSave(mMainCtx, "TAG :: " + String.valueOf(tag));
                    HttpLoggingInterceptor httpLogger = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
                        @Override
                        public void log(String message) {
                            if (mMainCtx != null){
                                S_FileManager.appHttpLogSave(mMainCtx, message);
                            }
                        }
                    });
                    httpLogger.setLevel(HttpLoggingInterceptor.Level.BODY);
                    // ------------------------------------------------------



                    // ------------------------------------------------------
                    // TODO [OK HTTP 객체 선언 실시]
                    // ------------------------------------------------------
                    //OkHttpClient client = new OkHttpClient();
                    OkHttpClient client = new OkHttpClient.Builder()
                            .connectTimeout(TIME_OUT_SECOND, TimeUnit.SECONDS) // [커넥션 제한 시간]
                            .readTimeout(TIME_OUT_SECOND, TimeUnit.SECONDS)
                            .writeTimeout(TIME_OUT_SECOND, TimeUnit.SECONDS)
                            .pingInterval(TIME_OUT_SECOND, TimeUnit.SECONDS) // [핑 요청 시간]
                            .addInterceptor(httpLogger) // [Http 통신 로그]
                            .retryOnConnectionFailure(false)
                            .build();

                    Request.Builder requestBuilder = new Request.Builder();
                    requestBuilder.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8;"); //TODO [헤더]
                    requestBuilder.addHeader("Cache-Control", "no-cache"); //TODO [헤더]

                    // [로그 출력 헤더 삽입]
                    Map<String, String> requestHeader = new HashMap<>();
                    requestHeader.put("Content-Type", "application/x-www-form-urlencoded; charset=utf-8;");
                    requestHeader.put("Cache-Control", "no-cache");

                    if (C_Util.mapNotNull(header) == true){

                        Set set = header.keySet();
                        Iterator iterator = set.iterator();
                        while(iterator.hasNext()){
                            String key = (String) iterator.next();
                            requestHeader.put(key, String.valueOf(header.get(key)));
                            requestBuilder.addHeader(key, String.valueOf(header.get(key))); //TODO [헤더 추가]
                        }
                    }

                    Request request = requestBuilder.url(String.valueOf(urlData)).build(); //TODO [requestBuilder 추가]
                    // ------------------------------------------------------



                    // ------------------------------------------------------
                    // TODO [웹 소켓 통신 이벤트 리스너 지정]
                    // ------------------------------------------------------
                    WebSocketListener listener = new WebSocketListener() {
                        @Override
                        public void onOpen(WebSocket webSocket, Response response) {
                            S_Log._W_(ACTIVITY_NAME + " : webSocketListener : onOpen", new String[]{String.valueOf(response)});

                            // TODO [구독 된 콜백 으로 메시지 반환]
                            try {
                                if (webSocketSubscriber != null && webSocketSubscriber.isDisposed() == false){
                                    webSocketSubscriber.onNext(String.valueOf(WEB_SOCKET_OPEN_CONNECT_SUCCESS));
                                }
                            }
                            catch (Exception es){
                                es.printStackTrace();
                            }
                        }

                        @Override
                        public void onMessage(WebSocket webSocket, String text) {
                            S_Log._W_(ACTIVITY_NAME + " : webSocketListener : onMessage", new String[]{String.valueOf(text)});

                            // TODO [구독 된 콜백 으로 메시지 반환]
                            try {
                                if (webSocketSubscriber != null && webSocketSubscriber.isDisposed() == false){
                                    webSocketSubscriber.onNext(String.valueOf(text));
                                }
                            }
                            catch (Exception es){
                                es.printStackTrace();
                            }
                        }

                        @Override
                        public void onMessage(WebSocket webSocket, ByteString byteString) {
                        }

                        @Override
                        public void onClosing(WebSocket webSocket, int code, String reason) {
                            S_Log._E_(ACTIVITY_NAME + " : webSocketListener : onClosing", new String[]{"Code : " + String.valueOf(code), "Reason : " + String.valueOf(reason)});

                            // -----------------------------------------------
                            // TODO [웹 소켓 닫기 수행 수행]
                            // -----------------------------------------------
                            try { webSocket.close(code, reason); } catch (Exception es){ es.printStackTrace(); }
                            // -----------------------------------------------


                            // ------------------------------------------------------
                            // TODO [리턴 데이터 반환]
                            // ------------------------------------------------------
                            try {
                                if (webSocketSubscriber != null && webSocketSubscriber.isDisposed() == false){
                                    webSocketSubscriber.onNext("");
                                    webSocketSubscriber.onComplete();
                                }
                            } catch (Exception ex){
                                ex.printStackTrace();
                            }
                            // ------------------------------------------------------

                        }

                        @Override
                        public void onFailure(WebSocket webSocket, Throwable t, Response response) {
                            S_Log._E_(ACTIVITY_NAME + " : webSocketListener : onFailure", new String[]{"Error : " + String.valueOf(t.getMessage()), "Response : " + String.valueOf(response)});

                            // ------------------------------------------------------
                            // TODO [리턴 데이터 반환]
                            // ------------------------------------------------------
                            try {
                                if (webSocketSubscriber != null && webSocketSubscriber.isDisposed() == false){
                                    webSocketSubscriber.onError(new Throwable("[webSocketListener] : [onFailure] : " + String.valueOf(t.getMessage())));
                                    webSocketSubscriber.onComplete();
                                }
                            } catch (Exception ex){
                                ex.printStackTrace();
                            }
                            // ------------------------------------------------------
                        }
                    };
                    // ------------------------------------------------------



                    // ------------------------------------------------------
                    // TODO [요청 로그 출력 실시]
                    // ------------------------------------------------------
                    S_Log._F_(mMainCtx, "startWebsocket :: WebSocket [연결] 실시", new String[] {
                            "TAG :: " + String.valueOf(tag),
                            "TYPE :: " + "GET >> REQUEST",
                            "URL :: " + String.valueOf(urlData),
                            "HEADER :: " + String.valueOf(requestHeader)
                    });
                    // ------------------------------------------------------



                    // ------------------------------------------------------
                    // TODO [웹 소켓 연결 수행 실시]
                    // ------------------------------------------------------
                    webSockets = client.newWebSocket(request, listener);
                    // ------------------------------------------------------

                }
                else {
                    try { subscriber.onError(new Throwable("[FAIL] : [startWebsocket] : mMainCtx Is Null")); subscriber.onComplete(); webSockets = null; } catch (Exception ex){ ex.printStackTrace(); }
                }

            } catch (final Exception e){
                // ------------------------------------------------------
                // [로그 출력]
                // ------------------------------------------------------
                S_Log._printStackTrace_(mMainCtx, S_FinalData.LOG_BUG_STATE, new String[] {
                        "startWebsocket :: Http WebSocket [EXCEPTION] 확인",
                        "TAG :: " + String.valueOf(tag),
                        "TYPE :: " + "GET >> EXCEPTION",
                        "EXCEPTION :: " + String.valueOf(e.getMessage())
                }, e);
                // ------------------------------------------------------


                // ------------------------------------------------------
                // TODO [리턴 데이터 반환]
                // ------------------------------------------------------
                try {

                    if (subscriber != null && subscriber.isDisposed() == false){
                        subscriber.onError(new Throwable("[EXCEPTION] : [startWebsocket] : " + String.valueOf(e.getMessage())));
                        subscriber.onComplete();
                    }

                    webSockets = null;

                } catch (Exception ex){
                    ex.printStackTrace();
                }
                // ------------------------------------------------------
            }

        });
    }
 

[결과 출력]

 

W  ===================================================================
[LOG :: CLASS PLACE :: com.example.javaproject.C_Module.C_WebSocket_Okhttp_Client_Module$2.onOpen(C_WebSocket_Okhttp_Client_Module.java:345)]
----------------------------------------------------
[LOG :: NOW TIME :: 2024-09-05 17:20:11 목요일]
----------------------------------------------------
[LOG :: DESCRIPTION :: C_WebSocket_Okhttp_Client_Module : webSocketListener : onOpen]
----------------------------------------------------
[LOG :: Response{protocol=http/1.1, code=101, message=Switching Protocols, url=https://javascript.info/article/websocket/demo/hello}]
W  ===================================================================




W  ===================================================================
I  [LOG :: CLASS PLACE :: com.example.javaproject.C_Module.C_WebSocket_Okhttp_Client_Module.request_Hello(C_WebSocket_Okhttp_Client_Module.java:537)]
I  ----------------------------------------------------
I  [LOG :: NOW TIME :: 2024-09-05 17:15:03 목요일]
I  ----------------------------------------------------
I  [LOG :: DESCRIPTION :: C_WebSocket_Okhttp_Client_Module : Send Message Emit : hello]
W  ===================================================================




W  ===================================================================
I  [LOG :: CLASS PLACE :: com.example.javaproject.C_Module.C_WebSocket_Okhttp_Client_Module$2.onMessage(C_WebSocket_Okhttp_Client_Module.java:359)]
I  ----------------------------------------------------
I  [LOG :: NOW TIME :: 2024-09-05 17:15:04 목요일]
I  ----------------------------------------------------
I  [LOG :: DESCRIPTION :: C_WebSocket_Okhttp_Client_Module : webSocketListener : onMessage]
I  ----------------------------------------------------
I  [LOG :: Hello from server, hello!]
W  ===================================================================

 

반응형
Comments