2018년 7월 9일 월요일

Communicate with Node Socket.IO to another Node server

현제 진행중인 프로젝트에서는 두개의 작동되는 별도의 서버가 있으며, 각자 기능이 분담되어있습니다.( 퍼포먼스 이슈를 피하기위해+여러 케이스를 연습해보기 위해)

기존에 완성된 웹사이트 프로젝트와 연계 프로젝트이나, 현제 구동중인 서버의 Spec과,
연계 프로젝트에서 요하는 CPU구동 수준을 비교/ Node의 특성(Single Thread)을 고려했을때, 모든 기능을 하나의 노드 프로젝트에 구겨넣는것은(물론 작동은 하겠지만) 만족스럽지 못할것으로 판단이 되었습니다.

클라이언트가 Serv2와 통신을 하기위해서, 굳이 Serv2에도 Serv1과 같은 Http프로토콜을 개설해 줄 수도 있으나, 이전의 프로젝트들을 구상하며 항상 발목을 잡았던 보안적인 측면을 강화하는 연습을 위해, Serv2는 외부와의 통신이 일제 없는 Serv1과 동일한 내부 내트워크망/ 알려진 포트만을 사용하는 로컬 서버로 지정합니다.

기획중인 DataDB의 내용은 보안이 특별히 중요하기 때문에 이런 서버 나누기는 여러 의미로 해볼 가치가 있어보입니다.

그러면 어떻게 Serv1과 Serv2가 통신을 하도록 할것인가 인데,
가장 단순하게 떠오른 방식은 역시 http통신 이었습니다.

하지만 socket 통신이 http통신보다 훨씬 유리할것 이라는 추측은 오래가지 않아 나오게 되었습니다.

(추후 바뀔수 도 있으나) 그럼 이제 Node간 socket통신을 가능캐 하는것이 목표가 되었는데, 다행히도 Socket통신을 매우 쉽게 모듈화 한 Socket.Io 패키지가 이미 있으며, 상당히 쓰이고 있었습니다. Npm의 Socket.io

사용할 패키지와 기초적인 구상은 끝났으니, 구동 테스트에 돌입하였습니다.



SocketIo에서 재공하는 기초예제입니다.
간단하게 http서버를1번라인에서 선언하며, 10번라인에서 8080포트로 열었습니다.
socket.io패키지의 이름을 io라 부르며, 방금 선언한 http서버를 인자값으로 넣어 host가 무엇인지 3번라인에서 명시합니다.
4-8번라인까지는 io가 연결된뒤, 기능들의 라우터입니다.
테스트용으로 저는 disconnect때에 로그를 찍게 했습니다.

이제 클라이언트 코드를 쳐보려고 하니...api를 훑어봐도 client용으로 그럴듯한 코드가 보이지 않았습니다..

잠깐 구글링 끝에, socket.io 개발팀은 socket.io-client 라는 이름으로 클라이언트 전용 패키지를 따로 만들어 놨던것 입니다..
Github의 socket.io-client

클라이언트 패키지도 찾았으니 마저 코드를 완성해 봅니다.



역시 기초예제입니다.
4번라인에 곧바로 socketio 서버와 통신을 선언과 동시에 시작합니다.뒤의 인자값에 서버 주소가 들어갑니다.

6번부터 마지막 라인까지는,연결 성공시, 이벤트 수락시, 연결 해제시 이벤트 헨들러들이네요.

둘다 저장하고, 서버,클라이언트 순으로 실행을 한뒤, 클라이언트는 곧바로 종료했습니다.


(좌측 : 서버 로그 , 우측 : 클라이언트 로그)

아- 완벽하고 짧게 작동하네요. socket.io 개발팀에게 찬사를..
이제 저는 Node1에서 실제 클라이언트(Client)에게 받은 정보를 토대로
Node2에게 해당 정보를 전송할 것이기에, 두 Node간의 이벤트 처리를 테스트 해 봐야 합니다.

간단하게 문자열, 숫자, JSON을 정상적으로 받는지 확인을 하면 될거 같네요.
Node1이 저에게는 socketio-client가 될것 이기 떄문에, io-client에서 io-server로  이벤트를 작동시킬것 입니다.

이런경우에는 emit이라는 함수를 사용하는것 같습니다.


io-client의 마지막 라인에 새롭게 추가했습니다.
emit함수의 첫번째 인자값은 서버로 전송하는 이벤트의 '이름' 입니다.
그 이후는 사용자가 원하는만큼 인자값을 설정이 가능합니다.
저는 (string,number,JSON) 이렇게 세개를 보내 볼것 입니다.

이제 io-server 코드를 봅시다.



3번 라인의 io.on 안에 새롭게 이벤트 헨들러를 작성하면 됩니다.
6번라인이 새롭게 추가되었습니다.
'pushData' 라는 이름의 이벤트가 들어오면, 6번라인이 해당 이벤트를 처리합니다.
받는 파라메터값은 (dataStr,dataInt,dataJSON) 이군요.
올바르게 데이터타입을 받았는가와, 올바르게 데이터를 받았는지 콘솔창에 뿌려줍니다.

이제 실행을 해 봤습니다.


(좌측: 서버 로그, 우측: 클라 로그)

Splender!완벽하게 읽어들입니다!



걱정관 달리, 정말 어처구니없을 정도로 손쉽게 만들어져 있는 Socket.IO덕분에 넘어야 할 산 하나의 허들이 상당히 낮아졌습니다. 최대한 효율적으로 쓰기위해서, Socket.IO를 사용하는것이 맞는지 한번만 더 확인한뒤 문제가 없다면, 기꺼이 행복하게 Socket.IO를 쓸 준비가 된것 같습니다...

댓글 없음:

댓글 쓰기