김보안의 블로깅
  • 🏠 Home
  • 📚 Project
    • Blockchain
      • 🎦 PickMe
      • 🎦 IoTC
      • 🎦 Blackchain
      • 📃 Gemology
      • 🎦 PickMe
      • 🎦 PickMe
    • AI
      • 👋 A.I. Dream Reader
      • 🎦 A.I. Dream Reader
    • Security
      • 🎦 SNAC
    • Education
      • 🎦 Smart Lecture
  • 🤸‍♂ Hobby
    • Music
      • Violin
      • Guitar
      • Piano
      • Drum
    • Flower
      • Flower Certificate
    • Sport
      • Ski
      • Skateboard
      • Golf
      • Boxing

2013년 10월 26일 토요일

[JAVA] Socket.io blocking(동기) Callback 방법

 SecureKim     오후 1:32     동기, 소켓, 자바, 콜백, Blocking, Callback, JAVA, Socket.io     No comments   

Socket.io

자바에서 Socket.io를 쓰기로 했고 저는 내부 통신 전부를 추상화된 모듈 형식으로 만들어야 했습니다.

자바는 기본적으로 Blocking으로 실행되지만, 서버인 Node.js는 Non-Blocking 입니다.

문제는 서버측에서 Emit해 주는 것을 자바에서도 비동기로 받는다는 것이었습니다.

자바스크립트에서는 비동기로 하고 싶으면 Callback을 이용해 쉽게 할 수 있는데

자바에서는 on이라는 함수가 비동기적으로 이벤트가 일어날 때 마다 받게 되어있더군요.

그래서 콜백을 직접 구현하기로 했습니다.

동작방식은 다음과 같습니다.
1.전역변수를 Null로 잡고, 자바측에서 Emit한 후 이 전역변수가 Null이 아닐때 까지 While문으로 체크합니다.
2.서버측에서 값이 전달되어 전역변수값이 바뀌면, 자바측에서 값을 받아오고 전역변수 값을 다시 Null로 만듭니다.
실제 서버에서 전달된 값이 Null일때만 조심하면 됩니다.
// 사용 : https://github.com/Gottox/socket.io-java-client
// Class명 : MyModule

static Object Emit_value=null; // 사용될 전역변수입니다.

//////////////////////////////////////////////////////////////////////////
...
public void on(String event, IOAcknowledge ack, Object... args) { 
// 이렇게 Thread 내부 on에서 event에 대한 arg를 받으면
// 그 값을 바꿉니다. 주의 할 점은 Emit_value 자체가 null 일 때 입니다.

                   Emit_value=null;
                   if(args[0]!=null){
                    Emit_value=args[0];
                   }
                   else Emit_value=-1;
               }
...
///////////////////////////////////////////////////////////////////////////

private synchronized Object callback(){
  while(Emit_value==null){try {
   Thread.sleep(20);
// 이 부분을 수정하여 timeout 이라는 변수를 하나 선언 한 후
// 다음과 같이 해주면 과도한 Block을 막을 수 있습니다. 
//Thread.sleep(timeout);
//timeout*=2; 
//if(timeout>5000) return -1;
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }}
   Object temp_value=Emit_value;
   Emit_value=null;
   return temp_value;
 }

private static String md5(String input){ //MD5 암호화
     String result = input;
     if(input != null) {
         MessageDigest md;
   try {
    md = MessageDigest.getInstance("MD5");
         md.update(input.getBytes());
         BigInteger hash = new BigInteger(1, md.digest());
         result = hash.toString(16);
         while(result.length() < 32) {
             result = "0"+result;
         }
   } catch (NoSuchAlgorithmException e) {
    e.printStackTrace();
   }
     }
     return result;
 }

public int reqLogin(String ID, String PW){
  try {
   socket.emit("c/reqLogin",new JSONObject().put("PW",PW).put("ID", ID));
   return (int) callback(); // Blocking 합니다.
  } catch (JSONException e) {
   e.printStackTrace();
  }
  return 0;
 }

//사용법 : MyModule 객체를 생성한 후, 사용하면 됩니다.
MyModule.reqLogin("bykim", md5("user_password"))


Callback 함수 While문 내부의 sleep(0)은 중요합니다.

저게 없으면 CPU 사용률이 100%가 되어 서버측에서 메시지는 보냈는데

정작 자바에서는 아무것도 못받고 소켓이 끊길 때 까지 기다리게 되는 수가 있습니다.

While문 돌 때 마다 System.out.println(); 를 찍어주면 느려지기(?) 때문에 제대로 돌아가지만
그것보단 Sleep() 이 낫겠죠?

참고 : Thread의 Context Switch에 걸리는 시간은 최소 10msec정도라고 하며
60msec정도가 한계인 irix,solaris 도 있습니다.
그리고 Sleep(0)의 경우, 다른 쓰레드가 준비 되었다고 해서 자신의 CPU의 선점을 넘겨주지 않으며,
우선순위가 서로 같아야 CPU가 넘어갑니다.

  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
이메일로 전송BlogThis!Twitter에서 공유Facebook에서 공유
최근 게시물 이전 게시물 홈

0 개의 댓글:

댓글 쓰기

페이지

  • 홈
  • Hobby

Categories

  • AI
  • android
  • AWS
  • Blockchain
  • Hardware
  • Javascript
  • mysql
  • Node.js
  • Plasma
  • review
  • Security
  • Study
  • Video
  • windows

Popular Posts

  • 회사 프록시와 인증서에 고통받는 그대를 위한 글 (Bash, Gradle, Python, wget, nodejs(npm), apt-get, cURL, git, yarn, androidStudio)
    대기업에 입사하면 장단점이 있는데, 단점 중에 하나가 회사에서 프록시를 사용하여 트래픽 감시를 하므로 프록시 설정을 해주어야 한다는 점 입니다. 특히, 회사에서는 https 트래픽도 감시를 하므로 인증서도 설정해 주어야 합니다. 그런데 문...
  • Termux 로 안드로이드에 우분투(GUI)와 VSCode설치하기
      많은 글들이 있지만 뭔가 대부분 잘 안됐다. 이번 기회에 정리한다. 0. 먼저 Termux와 Remote Desktop Manager를 설치한다. Remote Desktop Manager 대신 아래도 나쁘지 않다. 화면이 작지만 마우스 스크롤이나 ...
  • Node.js 에서 RSA 로 암복호화 하기
    Node.js 의 crypto 모듈은 기본적으로 제공되므로, npm 으로 설치할 필요가 없습니다. crypto 기본 모듈을 사용해 RSA 의 키로 암복호화 하는 방법을 알아 봅시다. 일단 그 전에 OpenSSL로 RSA Private Key...

Blog Archive

  • ►  2023 (1)
    • ►  1월 (1)
  • ►  2022 (10)
    • ►  12월 (1)
    • ►  11월 (3)
    • ►  9월 (1)
    • ►  8월 (1)
    • ►  6월 (2)
    • ►  3월 (2)
  • ►  2021 (9)
    • ►  12월 (3)
    • ►  11월 (1)
    • ►  6월 (1)
    • ►  5월 (2)
    • ►  4월 (2)
  • ►  2020 (12)
    • ►  10월 (1)
    • ►  9월 (2)
    • ►  7월 (1)
    • ►  6월 (1)
    • ►  5월 (5)
    • ►  4월 (1)
    • ►  2월 (1)
  • ►  2019 (14)
    • ►  10월 (2)
    • ►  7월 (1)
    • ►  3월 (4)
    • ►  2월 (2)
    • ►  1월 (5)
  • ►  2018 (14)
    • ►  12월 (2)
    • ►  11월 (4)
    • ►  10월 (1)
    • ►  8월 (2)
    • ►  5월 (4)
    • ►  1월 (1)
  • ►  2017 (12)
    • ►  10월 (2)
    • ►  9월 (9)
    • ►  5월 (1)
  • ►  2016 (8)
    • ►  10월 (2)
    • ►  8월 (1)
    • ►  6월 (1)
    • ►  1월 (4)
  • ►  2015 (6)
    • ►  12월 (3)
    • ►  10월 (1)
    • ►  6월 (1)
    • ►  5월 (1)
  • ►  2014 (10)
    • ►  11월 (1)
    • ►  9월 (1)
    • ►  7월 (1)
    • ►  6월 (1)
    • ►  5월 (3)
    • ►  4월 (1)
    • ►  3월 (2)
  • ▼  2013 (28)
    • ►  12월 (3)
    • ►  11월 (6)
    • ▼  10월 (6)
      • [Nginx] PHP-FPM 실행을 했는데 500 internal error 가 나온다
      • [CentOS] 삼바(SAMBA) 서비스가 실행이 안된다.
      • [JAVA] Socket.io blocking(동기) Callback 방법
      • [Java] Ant Build Failed
      • [UCrew] 발대식과 Ativ Tab 3 사용기
      • Power Mockup 라이센스 취득!
    • ►  9월 (6)
    • ►  8월 (1)
    • ►  7월 (3)
    • ►  6월 (3)

구독

글
Atom
글
댓글
Atom
댓글

로드 중입니다...

각오

직접 해보지 않은 것은 포스팅 하지 않겠습니다.

Copyright © 김보안의 블로깅 | Powered by Blogger
Design by Hardeep Asrani | Blogger Theme by NewBloggerThemes.com | Distributed By Gooyaabi Templates