본문 바로가기

프로그래밍/Node.js

[Do it! Node.js 프로그래밍] 12일차

1. 공부한 범위


[11] JSON-RPC 서버 만들기



2. 공부한 내용


[11] JSON-RPC 서버 만들기

 

11-1 JSON-RPC를 웹 서버에 적용하기

 

- RPC (Remote Procedure Call) 는 서버에 데이터를 요청해 응답받는 과정을 라이브러리에서 자동으로 처리한다.

- 로컬 단말에서 함수를 호출하는 것처럼 코드를 만들기만 해도 클라이언트와 서버 간의 데이터를 주고받는 기능이 동작하기 때문에 서버를 훨씬 쉽고 간단하게 만들 수 있다.

- JSON-RPC는 JSON포맷으로 데이터를 주고받을 수 있어 자바스크립트를 사용하는 노드 프로그램에서 더 자연스럽게 사용할 수 있다. 

 

JSON-RPC 모듈 설치하여 사용하기

- RPC를 이용하게 된다면 먼 거리에 있는 서버에 함수를 만들고 클라이언트에서 호출하거나 응답받는 과정을 모두 라이브러리에서 담당하여 개발자가 복잡한 네트워킹 과정을 신경 쓰지 않아도 되며 클라이언트에서 일반 함수를 사용하듯 서버에 데이터를 요청하기만 하면 된다.

- 클라이언트에서 스텁(stub)을 통해 서버로 요청을 보내면 서버에서는 해당 요청을 수행한 후 결과값을 응답으로 보내준다.

- 필요한 데이터를 서로간 주고받을 때 사용하는 데이터 포맷은 XML 또는 바이너리 포맷 등이 있다.

- JSON-RPC에는 OS에 영향이 없도록 다양한 언어로 작성된 라이브러리가 있다. 여기에서는 jayson 모듈을 이용한다.

- jayson 모듈을 사용할 때는 클라이언트 요청을 라우팅하는 라우터 미들웨어 다음에 jayson 모듈을 사용하게 되면 클라이언트가 특정 패스로 요청할때만 JSON-RPC로 처리하도록 만들 수 있다.

- JSON-RPC를 사용하기 위해 등록한 함수들은 핸들러라고 부른다. 해당 정보들은 handlers 폴더를 만든 다음 handler_info.js에 기록해둔다.

 

- config.js에 입력된 내용들 중에서 JSON-RPC로 처리되도록 설정된 정보들은 jsonrpc_api_path 속성에 들어있다.

 

- 위 코드는 "http://localhost:3000/api"를 통해 RPC를 요청할 수 있음을 의미한다.

- 핸들러는 서버 쪽에서 만들어지는 함수의 일종이라고 이해하면 된다.

- module.exports에 할당되는 handler_info 객체는 배열로 이루어져 있으며 여러 속성값을 해당 배열 안에 작성하여 적용시킬 수 있다.

- 배열 내의 속성들 중 file 속성은 핸들러 모듈 파일 이름이며, method 속성은 등록한 핸들러의 이름이다.

- 핸들러 이름으로 클라이언트가 호출하기 때문에 클라이언트는 서버에 어떤 이름으로 핸들러가 등록되어 있는지 알고 있어야 한다.

 

echo 함수 만들어 실행하기

- echo 핸들러는 클라이언트에서 보낸 데이터를 그대로 다시 보내주는 기능을 하는 함수다.

 

- 에코 함수는 두 개의 파라미터를 전달받는다.

- 첫 번째 파라미터는 파라미터로부터 전달받았고 배열로 이루어져 있다.

- 두 번째 파라미터는 함수이며 클라이언트에 응답할 때 사용한다.

- 콜백 함수 또한 두 개의 파라미터를 전달받으며 첫 번째는 오류 전달을 위해, 두 번째는 정상적인 데이터를 전달할 때 사용한다.

- echo 함수는 입력받은 데이터를 그대로 보내주는 기능을 하기 때문에 클라이언트로부터 받은 params를 그대로 다시 되돌려보낸다.

 

- head 태그 내의 스크립트를 참조해오는 부분을 통해 jQuery와 jQuery.jsonrpc를 불러온다.

 

- $.jsonRPC.setup() 메소드를 호출하면 기본 설정이 가능해진다. 해당 메소드 내 endPoint 속성에는 접속할 서버의 URL을 넣게 된다.

- $.jsonRPC.request() 메소드를 호출하여 클라이언트는 서버에 요청이 가능하다.

- 서버에 요청할 때 전달되는 객체의 속성

id : 요청 ID를 지정할 수 있다. 이 속성은 서버로부터 받는 응답을 구별하는 데 이용된다.

params : 서버로 보낼 데이터를 넣는 배열 객체다.

success : 응답을 성공적으로 수신했을 때 호출되는 콜백 함수다.

error : 오류 응답을 받았을 때 호출되는 콜백 함수다.

- 서버에 id 속성을 여러 번 요청하면 각 요청을 구별하는 역할을 하게 된다.

- success 속성에 설정한 함수에는 data라는 이름의 객체가 포함되어 전달된다.

- data 객체의 속성

id : 요청할 때 전달한 id값이 들어있다.

jsonrpc : JSON-RPC 스팩의 버전을 표기한다.

result : 응답 데이터가 배열 객체의 형태로 들어있다.

- 기존의 웹 표시 방법과 RPC의 가장 큰 차이점은 서버에서 응답 받는 것이 웹 문서가 아닌 데이터라는 점이다.

- 웹 문서는 로컬 PC나 모바일 단말에 저장했다가 화면에 출력시키며, 서버로부터 받는 데이터만 받아 화면의 일부를 업데이트하는 방식이기 때문에 웹 문서를 완전히 새로고침할 필요가 없어지게 되며 응답 속독가 훨씬 빨라지게 된다.

- 서버쪽에 echo 함수를 만들어 등록한 후 클라이언트의 요청 과정만 반복 작업하면 되기 때문에 여러 기능을 더욱 짧은 시간 내에 만들 수 있게 되며 이것이 RPC 방식의 가장 큰 장점이라 할 수 있다.

 

echo 함수의 오류 테스트하기

- echo_error내의 함수는 클라이언트에서 보낸 데이터를 확인한다. 

- 배열에 들어있는 요소들의 개수를 확인하게 되며, 2개보다 작을 경우 콜백 함수를 통해 오류를 반환한다.

- 오류 객체에는 code와 message 속성이 들어간다.

 

- 핸들러 모듈 파일을 만들어 새로운 기능을 추가한다면 handler_info.js 파일에 전부 등록해야 정상 작동하게 된다.

 

- echo_error.html 파일의 스크립트 부분으로, 요청하기 버튼을 눌렀을 때 호출되는 코드는 echo.html과 같으나, 요청할 때의 method인 호출할 함수 이름이 echo에서 echo_error로 변경되었다는 차이가 있다.

- echo_error를 활용하면 사용자가 오류 상태를 웹 화면에서 확인할 수 있게 된다.

 

11-2 계산기 모듈 추가하여 실행하기

 

- 개발자가 더하기 기능을 만들어 호출하기 위해서는 3가지 단계를 거치게 된다.

1) 서버 쪽에 함수가 들어있는 핸들러 모듈 파일을 만든다. 더하기 함수를 정의하고 해당 함수를 module.exports에 할당하는 것이다.

2) 새로 만든 핸들러 모듈 파일을 등록한다. handler_info에 만든 모듈의 이름과 클라이언트에서 호출할 때 사용할 이름을 등록한다.

3) 클라이언트 웹 문서에서 서버에 만들어 둔 함수를 호출한다. 이 과정은 JSON-RPC 라이브러리에서 정한 방식을 사용하며, 미리 만들어 둔 함수의 이름과 파라미터를 입력하면 된다.

 

1단계 : 핸들러 모듈 만들기

 

- handler 폴더 내에 add.js 파일을 만들어 모듈을 작성한다.

- 전달받은 params 배열 객체에 두 개의 객체가 있는지 확인 후 두 값을 더해 응답으로 반환한다.

- 일반적인 더하기 함수와 같은 기능을 하나 결과 값을 반환하지 않고 콜백함수로 전달한다는 차이가 있다.

 

2단계 : 핸들러 모듈 파일 등록하기

 

handler_info.js 내의 handler_info 배열에 add 모듈을 추가한다.

 

3단계 : 클라이언트 웹 문서에 호출하기

 

- 웹 문서에서 aInput과 bInput을 통해 더할 두 숫자를 입력받는다.

 

- head 태그 내의 script 태그를 통해 jQuery를 작성한다. 내용은 웹 문서에서 입력한 두 값을 전달받은 후 서버에 정의된 add함수를 호출해 계산을 수행하는 것이다.

 

11-3 데이터베이스에서 사용자 리스트 조회하기

 

- JSON-RPC를 통해 만들어진 핸들러 모듈 함수에서도 데이터베이스에 접근할 수 있다.

 

- 위 코드에서의 database 객체는 서버가 실행될 당시 전역 변수에 속성으로 추가되었기 때문에 global.database라 입력함으로써 참조가 가능해진다.

- 데이터베이스에 접근할 수 없다면 클라이언트에 오류를 보내게 된다.

 

- 사용자 검색 결과는 배열 객체로 만든 후 콜백 함수의 두 번째 파라미터로 전달한다.

- 완성된 핸들러 모듈 파일은 handler_info.js 내부에 있는 배열에 등록한다.

 

- 요청 버튼을 클릭하면 서버에 데이터베이스를 요청하는 모듈을 불러오도록 한다.

- 정상 응답과 오류 응답을 위한 코드는 따로 분할해 처리한다.



 

- 성공 시 응답으로 받은 객체는 배열 형태를 띄기 때문에 forEach를 통해 각 아이템의 id와 name값을 웹 화면에 표시하게 된다.

- 다른 형태로 응용하고자 한다면 클라이언트 요청을 담당하는 웹 문서의 JS코드에서 두 가지를 변경한다.

1) 요청을 보낼 때 사용하는 id, method, params

id는 각 기능별로 고유한 숫자를 부여할 수 있다.

method는 서버에 만든 함수를 호출할 때 사용하는 이름

prarams는 서버에 전달할 데이터를 배열 형태로 만든 것이다.

2) 성공 응답을 받았을 때 사용하는 processRespose() 메소드의 코드

 

11-4 데이터 부분을 암호화하기

 

- RPC 방식을 사용할 때는 데이터만 주고받는 경우가 많기 때문에 데이터만 암호화하는 경우가 많다.

- 노드에서는 데이터를 암호화하는 crypto 모듈을 기본적으로 제공하나, 웹 브라우저에서 암호화한 데이터와 호환되지 않는 경우도 발생할 수 있다.

 

- 브라우저에서는 params 배열에 넣어 전달하는 데이터를 암호화한다. 해당 데이터는 서버에 도달 후 복호화해 처리하게 된다.

- 서버에서 모듈을 수행 후 나온 결과물을 다시 암호화해 클라이언트로 되돌려보내면 클라이언트에서 해당 데이터를 복호화해 화면에 출력하게 된다.

- 웹 브라우저의 자바스크립트에서 사용 가능한 암호화 라이브러리는 crypto-js가 대표적이다.

 

- crypto-js를 다운로드 후 내장 파일 중 aes.js파일을 cryptojs 폴더를 생성해 안에 넣어 링크해 사용한다.

- aes.js 내부에는 AES 표준 알고리즘으로 암호화 및 복호화 가능한 함수가 들어있다.

 

- 노드에 설치한 모듈인 'crypto-js'를 require 메소드를 통해 불러온다.

- 암호화와 복호화 코드는 클라이언트의 것과 거의 같다.

- crypto 모듈 내에는 AES객체가 들어있고, 그 안에는 encrypt()와 decrypt() 메소드가 있다. 이들 메소드를 호출하게 되면 암호화나 복호화가 진행된다.