IO시그널 기초 실습
본 글에서는 iosignal-cli 프로그램을 설치 후 IO시그널의 기초 개념과 사용법을 체험해봅니다.
CLI(Command Line Interface) 프로그램이란 윈도우 명령창이나 리눅스 터미널 창에서 문자 명령어로 실행 가능한 프로그램을 뜻합니다. NodeJS 를 지원하는 맥, 윈도우, 리눅스 모두에 설치 가능합니다.
iosignal-cli 설치 후 명령어 한줄만 입력만 하면 IO서버와 클라이언트 실행할 수 있으므로 비전문가도 설치하여 사용할 수 있습니다. 교육 용도 뿐 아니라 실제 서버 운영 및 테스트에 사용될 수 있는 유용한 프로그램입니다.
iosignal-cli 설치하기
우선 NodeJS 개발환경이 설치되어 있어야 합니다. NodeJS(노드 제이에스)란 자바스크립트(Javascript)언어로 서버 및 데스크탑 프로그램을 만들수 있는 개발 환경입니다.
1. NodeJS 를 먼저 설치해줍니다.
아래의 공식 사이트를 방문하면 운영체제에 따른 설치 파일을 다운로드 할 수 있습니다. 설치할 버전을 선택해야할 경우 LTS(공식안정) 버전을 선택하시는것이 좋습니다. NodeJS 개발 환경은 윈도우(Windows), 맥(Mac), 리눅스(Linux) 운영체제 모두를 지원합니다. 자세한 설치방법은 이미 여러 환경 별로 자세하게 소개된 공개 글을 참고하시는것이 더 좋을것 같습니다.
노드 개발환경을 설치 후 터미널 환경에서 npm 이란 명령을 사용할 수 있습니다.
NPM(Node Package Manager)을 이용하면 개발환경에 필요한 소스 코드나 프로그램을 다운로드해서 설치할 수 있습니다. iosignal-cli도 NPM 명령문을 통해 설치하게됩니다.
2. npm 명령으로 설치
윈도우 환경인 경우 cmd(명령프롬프트) 창을 이용하거나 좀더 많은 기능을 제공하는 파워쉘(PowerShell)을 설치한 뒤 사용할 수 도 있습니다. 주의 할 점은 명령 프롬프트를 실행시 관리자 권한으로 실행해주셔야 합니다.
CLI 프로그램으로 설치하여 사용하기 위해선 전역(global)설치라는 걸 해줘야 하므로 -g 옵션을 반드시 포함시켜야 합니다.
$ npm install -g iosignal-cli
맥과 리눅스 환경의 경우도 관리자 권한으로 설치가 필요하므로 sudo 라는 명령을 통해서 실행해줘야합니다.
$ sudo npm install -g iosignal-cli
(필요시 관리자 암호입력)
3. iosignal-cli 명령어
CLI 프로그램이 잘 설치된 경우 터미널 명령창에서 아래의 명령어를 실행 할 수 있습니다.
io-server: IO시그널 서버를 시작 합니다.io-client: 서버에 접속하는 클라이언트 프로그램을 시작 합니다.- 단축명령어
- io-server 대신
ios을 사용해도 됩니다. - io-client 대신
io을 사용해도 됩니다.
- io-server 대신
4. 서버 실행하기
별도의 옵션없이 io-server 라고 명령하면 기본 포트번호(port 7777)로 웹소켓 연결이 가능한 서버가 구동됩니다.
$ io-server
// 기본 포트 번호 7777 로 서버가 작동됨
웹소켓 포트번호 지정하기
옵션 -l (Listen ) 과 숫자를 이용하여 웹소켓 연결용 포트 번호를 지정할 수 있습니다.
- 주의사항. 소문자 l(엘)입니다. 대문자 L옵션은 웹소켓이 아닌 아두이노 접속용 콩소켓 포트 번호를 지정합니다.
$ io-server -l 5555 // 포트 5555번으로 웹소켓 연결을 받을 경우
서버나 클라이언트 프로그램을 종료하려면 .exit 명령을 입력하거나 일반적인 프로그램 종료 명령인 ctrl+c 키를 누르면 됩니다.
옵션 없이 서버를 실행 후 종료하지 말고 다른 새 터미널창을 열고 아래와 같이 클라이언트 실행을 해보세요
5. 클라이언트 실행
io 명령어를 옵션이 없이 실행할 경우, 로컬호스트(동일 컴퓨터)에서 구동되는 서버의 기본포트(7777)로 웹소켓 접속을 시도합니다. 위에서 서버를 옵션 없이 실행 후 종료 하지 않은 상태에서, 새로운 터미널 창을 열어서 옵션 없이 io 명령을 실행하면 위 서버에 연결 됩니다.
$ io
// 옵션없이 실행시 아래와 동일
$ io -c ws://localhost:7777
- c (connect 접속)옵션 사용
보통 클라이언트가 서버에 접속하려면 -c(connect접속)옵션을 이용하여 프로토콜 이름(ws or wss), 서버의 주소 및 포트 번호를 명시해줘야 합니다. 기본 웹소켓 연결은 ws://url:port 의 형태이고 ws:// 이 프로토콜을 명시하는 부분입니다. 웹소켓 포트가 TLS 로 암호화되는 경우 프로토 콜을 wss:// 으로 명시합니다. ws와 wss의 차이는 웹브라우저의 통신 내용이 노출되는 http 연결과 통신 연결이 SSL/TLS로 암호화 되는 https 차이로 이해하시면 됩니다.
// 로컬 서버 접속시
$ io -c ws://localhost:7777
// 외부 서버 접속시 예.
$ io -c ws://test.remocon.kr:7777
// 443 포트로 TLS기반 웹소켓 접속을 받는 서버의 경우 포트번호가 생략될 수 있습니다.
$ io -c wss://server.com/ws
6. 시그널링(메시지 전송) 기본
본 글에서는 서버를 경유한 클라이언트들간의 메시지 소통(메시징)을 포괄적으로 시그널링이라고 표현합니다. IO시그널은 시그널링 규칙(프로토콜)을 기본 제공합니다. MQTT 브로커 같은 채널명으로 구독/발행(Pub/Sub)하는 기능과 더불어 새로운 시그널링 규칙을 추가하였습니다. 즉, 이미 MQTT 를 사용해보신 분들이 익숙한 publish, subscribe 명령을 사용할 수도 있습니다. 하지만 MQTT 에서 제공하는 채널명의 패스(Path)개념 등이 지원되지 않는 등의 큰 차이가 있습니다. 참고로 시그널은 패스(path)라는 개념 대신 타겟(target)과 토픽(topic)으로 구성되는 태그(tag) 개념을 사용합니다. 일단은 태그를 MQTT에서 구독 발행시 사용하는 채널명으로 생각하시면 됩니다.
우선은 MQTT 같은 PubSub 메시징에 이미 익숙한 분들을 위해 구독과 발행 명령에 해당하는 대체 명령어를 소개합니다.
일반적인 PubSub 기반 브로커는 아래와 같은 명령문을 사용합니다.
- subscribe 채널을 구독하는 명령입니다.
- publish 채널로 발행하는 명령입니다.
IO시그널 경우 대체 용어를 사용합니다.
- subscibe 대신 listen , publish 대신 signal 명령어를 사용합니다.
- listen 은 구독(subscribe)의 기능과 함께 발행된 메시지가 수신된 경우 어떻게 처리할지를 정의하는 명령입니다.
- 프로그래밍 환경에서는 구독하는 채널 태그와 함께 핸들러 함수를 등록합니다.
- CLI 환경에서는 구독할 태그(채널명)를 지정해주는 기능을 하며, 메시지 수신 핸들러 함수를 정의할 수 없으므로 수신된 메시지를 단순히 화면에 출력해 줍니다.
- signal 은 발행(publish)을 대체하는 이름으로 채널을 사용하는 발행 개념보다 좀 더 포괄적인 신호 전달을 의미 합니다.
- publish와 subscribe 함수도 마찬가지로 사용 가능합니다. 별도 문서로 소개드립니다.
- 참고로 CLI 환경에서 명령문은 항상 앞에 점(dot) ‘.’ 을 붙여서 입력합니다.
7. CLI 명령문과 개발환경에서 함수 호출문의 차이
프로그램 개발환경에서는 아래와 같은 함수 호출문을 사용하지만
io.listen('channel', handlerFunction )
io.signal('channel','message')
CLI 명령창 환경에서는 아래와 같이 띄어 쓰기로 명령과 인자값(태그, 메시지 등)을 구분합니다.
> .listen channel
> .signal channel message
8. 시그널 전송
CLI 프로그램을 설치 후 아래의 예제로 따라해 보시면, 시그널링의 기본 기능을 체험해보실 수 있습니다. 여기서는 가장 기본이 되는 멀티캐스트와 유니캐스트의 개념을 실습 예제로 소개하고 있습니다.
8-1. signaling 유형
- 멀티캐스트(multi-cast): 채널을 구독한 구독자 모두에게 메시지를 전송합니다.
- 유니캐스트(uni-cast): 하나의 특정 수신자에게만 메시지를 전송합니다.
가령 채널 구독자가 다수인 경우 한번의 발행 메시지가 다수의 구독자에게 전달되게 됩니다. 일반적인 PubSub 메시징을 멀티캐스트로 볼 수 있습니다. 채널명만 알면 누구나 송신 및 수신이 가능합니다.
이와 달리 특정한 클라이언트에게만 메시지를 전달하는 경우를 1:1 통신 또는 유니캐스트이라고 표현합니다. IO시그널의 경우 유니캐스트 부분에서 기본 PubSub 메시징 방식과 차별화 된 기능을 제공합니다. 아래 예제는 시그널링을 통해 이 두 방식의 통신이 어떻게 수행되는지 참고하실 수 있습니다. 홈채널이나 토픽(topic)등을 포함하는 고급 태그 사용법은 별도의 문서로 소개 드리겠습니다.
8-2. 준비
화면에 3개의 터미널 창을 열어 준비합니다. 1개는 서버, 나머지 2개는 클라이언트로 사용하게 됩니다.
8-3. 서버 구동
첫번째 화면에서 아래와 같이 입력하여 서버를 구동합니다. 서버는 포트 7777 을 통한 웹소켓 연결을 대기합니다.
$ io-server
// 서버 실행 시 출력되는 정보들은 서버에서 사용되는 포트번호 같은 다양한 옵션 상태를 알려줍니다.
8-4. 클라이언트 A
이번엔 아래와 같이 io 명령을 실행하여 클라이언트 A를 구동하여 로컬 서버에 접속하게 합니다.
$ io
channels: Set(0) {}
Connecting to ws://localhost:7777
ready: cid:?7SbD
접속이 성공할 경우 ready 라는 표시가 뜨고 뒤에 나오는 ?7SbD 가 CID입니다. 여러분 화면에는 다른 값이 뜹니다.
CID(Communication ID) 커뮤니케이션 ID란?
IoT 장치들이 서로 소통할 때 사용하는 고유값으로 이메일(email) 주소 같은 역활을 합니다.
접속 시도 후 뜨는 ready 는 서버에 접속 뒤 서버로부터 CID를 부여 받은 상태를 의미하며 동시에 통신(시그널링)이 가능한 상태임을 알려줍니다. 만일 ready 표시가 뜨지 않은 경우 서버와의 접속에 문제가 있는 경우입니다. CID 는 1:1 통신에서 사용되는 중요한 정보입니다. email주소를 알아야 메일을 보낼 수 있듯이 CID를 알아야 다이렉트 시그널 전송이 가능합니다.
현재와 같이 로그인 과정이 없이 접속한 경우 서버는 익명 접속 클라이언트용 임시 CID 값을 부여 합니다. 이 값은 해당 접속 중에만 유효하고 매번 접속시 마다 변경됩니다. 반면 로그인 인증을 완료한 디바이스의 경우, 서버에 이미 등록된 고유 CID값이 사용됩니다.