프로그래밍/서버, DBMS

[Node.js] Node.js와 외부 프로그램(Java, C, C++) 연결 (bridge)

포도알77 2019. 3. 4. 16:08

 서버를 만들다 보면 NPM 패키지에 포함되지 않은 기능이 필요한 경우가 생긴다.

 이런 경우, 어쩔수 없이 다른 프로그래밍 언어를 사용해야하는 경우가 발생한다. 또한 성능 문제로 반드시 C,C++를 써야하는 경우가 생기기도 한다. 

 Node.js에서 타 언어 프로그램을 호출하는 경우 여러가지 방법이 있지만, 나의 경우에는 한가지 프로그램만 실행하면 되었기 때문에 child_process 패키지의 exec를 사용했다. (터미널 터맨드와 동일) 


 (1) STDOUT을 이용한 처리 방법

 물론 이 방법은 터미널 명령이기 때문에 위험하다. (하지만.. 뭐 소스가 변조되지 않는 이상은 문제가 없을 것이고, 이미 변조 단계에 들어섰다면 서버 소스와 DBMS 정보를 다 털린것과 다름없기 때문에..)
  
 var exec = require('child_process').exec;
exec('./program ./programInputRedirect.txt',
  function callback(err, stdout, stderr){
    if (err){
      console.error(err);
    }
    //stdout 응답 : { success : true/false, data : .. }
    var result = JSON.parse(stdout);
    if(result.success){
      ..
    }
});


 아무튼 위의 코드는 Node에서 C++ 프로그램을 실행하는 명령인데, 커맨드 명령이기에 입력 파일을 redirect 또는 직접 아규먼트로 던져줄 수 있다.


 응답은 C++ 프로그램에서 stdout에 JSON 형태로 던져준다. 이후 이 결과를 Node 콜백으로 가져오며, JSON으로 파싱해서 처리하는 로직을 가진다. 



 

 (2) Bridge 방법 


 사실 C, C++의 경우 브릿지 할 수 있는지는 모르겠지만, Java의 경우 가능하다. 


 우선 개념은 개발한 Java 프로그램을 Jar 파일로 변환하고, 이 Jar 파일에서 접근 가능한 함수를 Node.js상에서 직접 호출하는 것이다. 


 이 방법이 위의 child_process보다 획기적으로 빠르다거나, JVM 로드 시간이 적은지는 모른다. 

다만 훨씬 더 코드가 깔끔해지는 것은 확실하다.

var java = require('java');
var jarFilePath = __dirname+'/path../program.jar';

java.classpath.push(jarFilePath);
var progInstance = java.import('program.abc.defg')();

var result = progInstance.funcABCSync(param1,...);


 우선 java 패키지를 설치한다. jdk 1.7까지 기본적으로 지원하고, 1.8부터는 별도의 추가 설치방법이 필요하다고 한다.

 만약 java 패키지 설치시 계속해서 permission 에러가 발생하면 아래와 같이 설치를 시도하자.

  

sudo npm install java --unsafe-perm=true --allow-root


 그리고 jar 파일의 FilePath값을 지정하고, 이를 java.classpath.push함수에 전달하여 입력한다.
 그런 다음 java.import를 통해서 패키지를 import하고 인스턴스를 생성한다.

 이후 java 프로그램에서 정의한 함수 뒤에 Sync를 붙여주면, 해당 함수와 동기화되어 함수 종료후 그 결과를 리턴해준다.  



페이스북으로 공유카카오톡으로 공유카카오스토리로 공유트위터로 공유URL 복사