Technical WebRTC

WebRTC로 화상채팅 만들기-1편 ( feat. Google Cloud )

이 글에서는 WebRTC + Nodejs를 사용하여 Web에서 화상채팅을 하는 기능을 만들어 보려고 한다. 필자는 WebRTC, Nodejs에 대해서는 잘 알지 못하는 사람이다.
( 추후 Nodejs는 React로 변경될 수 있다 )
이 글에서는 초보자의 입장에서 화상채팅을 어떻게 만드는지 알아보도록 하겠다.

  1. 왜 Web 화상채팅인가?
    • Web을 선택한 이유
      Mobile, PC 와 같은 플랫폼들을 이용하여 만든 Application들은 편리하긴하지만 항상 설치해야 한다는 문제점을 가지고 있다.
      사용자들이 점점 Light한 Application사용 경험을 원하는 현재상황에서 이런 문제점은 Application의 사용율을 저하시킨다.
    • 화상채팅을 선택한 이유
      코로나와 같은 상황을 겪으면서 원거리 커뮤니케이션에 대한 Needs가 필요하게 되었다. 설치형 어플리케이션의 경우 설치해야 된다는 불편함 때문에 사용을 잘 안하게 되었고, 간편하게 웹 페이지만 열어서 화상채팅을 하게되면 사용을 쉽게 할 수 있을 것이라 생각되었다.
    • 결론
      사용자들이 더 간단하고 편하게 자주 화상채팅을 쓸 수 있도록 Web으로 화상채팅을 만들어 보게 되었다.
  2. 목표
    1. 서버구축 : Web 화상채팅 개발에 필요한 서버를 구축한다
    2. 1:1 화상채팅 개발 : WebRTC를 통하여 1:1 화상채팅을 개발한다
    3. Multi 화상채팅 개발 : N명이서 대화 가능한 화상채팅을 개발한다
    4. Text채팅 개발 : 텍스트 채팅 기능을 개발한다
    5. 파일공유기능 개발 : 파일 공유 기능을 개발한다

그럼 이제 1편 서버 구축에 대해 시작하도록 하겠다

  1. 구성
    undefined
    1. 먼저 Codepen을 이용하여 웹서버를 만든다(유료결제 회원만 가능, 유료결제가 안된다면 github페이지를 사용해서 웹페이지를 만든다)
      => 이 서버를 통해 웹 브라우저에서 javascript가 실행될 것이다.
    2. Google Cloud를 사용하여 Ubuntu + Nginx + Nodejs 서버를 만든다.
      Nginx를 사용해서 Proxy서버를 만들고 하위에 Nodejs WebSocket을 만드는 방식으로 만든다 .
      Nginx를 Proxy서버로 만들어보기 위해 이렇게 했으며, Nodejs만 설치해도된다. (이렇게 처리시 웹페이지 처리 속도가 비약적으로 빨라진다는 얘기를 들었다)
      => WebSocket 서버는 Signaling 서버가 된다. Signaling 서버는 연결된 웹 브라우저간의 신호 전송의 역할을 할 것이다. (상대가 접속했는지 여부 등을 이 서버를 통해 전송한다 )
    3. P2P 연결의 중계서버는 구글에서 무료로 지원하는 Google STUN 서버를 사용한다.
      [ 서버정보 ]
      stun.l.google.com:19302 ( DNS )
      74.125.31.127:19302 ( IP )
      두개의 NAT 네트워크로 연결된 시스템을 연결하려면 UDP Hole Punching 이라는 방식을 사용한다.
      => 이를 이용하여 사용자의 Web Browser를 서로 P2P 연결 시킨다.
      [ UDP Hole Punching ]
      undefined
      그림에서 PC1과 PC A는 NAT로인해 연결될 수 없다.
      NAT내부에서 Private IP를 사용하기 때문에 PC A에 접근할 수 있는 주소가 없어 접근이 불가능하다.
      undefined
      하지만 중간에 STUN 이라는 중계서버를 설치하면 가능하다.
      PC1과 PC A가 STUN 서버에 UDP로 접속하면 NAT네트워크가 외부로 빠져나가면서 랜덤한 포트를 열게 되는데 역으로 이 Port를 통해 접속하게 되면 PC 1에서 PC A로의 접속이 가능하다.
      여기서 STUN서버는 각 NAT에서 열어놓은 Port를 다른 컴퓨터에게 전달해 주는 역할을 하게된다.
      그래서 3번과 같이 PC 1이 10.111.111.115:1000으로 연결하면 192.168.0.1의 Private IP를 타고 PC A에 도달할 수 있게 된다.
    4. P2P로 WebBrowser간 연결이 완료되면 이제 영상 및 음성을 서로에게 전송하면된다.

2. 왜 Google Cloud를 사용하는가?
이유는 딱히 없다. AWS, Naver Cloud는 이미 사용해봤기 때문에 새로운걸 사용해본다.
그리고 Google Cloud는 처음 1년동안 $300는 무료로 제공된다.
서버 구성을 해보는 사람을 위해 필자가 비교한 자료를 공유한다.
아래 표는 최저사양에 1Core, 1GB 메모리를 기준으로 적었다.
개인적으로 amazon의 cloud서비스가 가장 편리하다.
초기 설치 비용은 Naver가 가장 싸며, amazon은 Outbound Traffic 비용이 싸다.
google cloud는 아직 한국 Region 선택이 불가능하다는 점이 단점이다.
$18.66($0.05/GB) 라고 써져있으면, 한달 유지비용 $18.66, 1GB outbound 당 $0.05의 요금이다
KT, Naver의 경우 traffic 사용양에 따라서 요금이 변경된다.

회사googleamazonktNaver
가격$18.66($0.05/GB )트래픽 국가별로 다른 요금제$16.64($0.02/GB)트래픽 국가별로 다른 요금제$18.85($0.05~0.07/GB)트래픽 국가별로 다른 할인율$10.78($0.05 ~ $0.083/GB) 해외트래픽 요금 동일
지역서울서울서울서울
미디어 서버Video Intelligence API 베타 버전 사용자체 미디어 서버 지원아마존 S3 API 일부 허용자체 미디어 서버 지원
편의성4점4점2점3.5점
출처 : 각 회사의 공식 사이트( kt, naver의 경우 한화로 되어있었는데 환율계산을 하면서 부정확한 부분이 있다 )

3. Google Cloud 서버 설치
3-1. Google Cloud에 접속한다
https://cloud.google.com/

3-2. Console에 접속한다
3-3. VM인스턴스 화면에 들어간다
undefined
3-4. 인스턴스 만들기 클릭
3-5. 이제 원하는 사양에 맞춰 선택하면 된다. 필자는 아래와 같이 선택하였다
undefinedundefined
3-6. 인스턴스가 만들어졌으면 SSH 접속Key를 등록한다 ( SFTP가 필요없으면 안해도됨 )
왼쪽 패널에 ‘메타데이터’ 에 들어가면 SSH키를 등록할 수 있는 화면이 나온다.
undefined
3-7. 키 생성하기
Google Cloud Platform의 편의성을 저하시키는 부분이다.
AWS와 달리 Google Cloud는 키를 생성해주지 않는다.
Putty 또는 Openssl 을 사용하여 키를 생성해야 된다.
필자의 설명이 부족하면 아래 링크를 이용해 좀 더 자세히 보도록 한다.
https://gongjak.me/2016/08/01/ssh%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%B4%EC%84%9C-vm%EC%97%90-%EC%A0%91%EC%86%8D%ED%95%98%EA%B8%B0/ 

3-7-1. putty 설치
아래 링크에서 putty를 설치한다
https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html

3-7-2. puttygen 실행
putty를 설치하면 puttygen이 같이 설치되는데 puttygen을 실행한다

3-7-3. 키생성

3-7-3-1. Generate 클릭 : 이 버튼을 클릭하면 로딩 화면이 나온다. 100%가 될때까지 마우 스를 움직인다

3-7-3-2. 위의 그림에서 2번 부분의 텍스트를 복사한다.
그 전에 반드시 Key comment란에 자신의 구글 계정을 입력한다

3-7-3-3. 복사한 값을 3-6의 메타데이터의 SSH Key란에 넣어준다
혹시 모르니 키 값은 저장하여 보관하도록 한다
3번, 4번 부분을 각각 test.pub, test.ppk 로 저장한다

3-8. 네트워크 고정주소 생성
이제 네트워크 고정주소를 생성해야된다. (유료)
필수는 아니지만 만약 이걸 설정하지 않는다면 서버가 Restart 될때마다 IP주소가 바뀔 것이다.

3-8-1. VM인스턴스 화면으로 다시 돌아간다.
여기서 네트워크 상세보기를 클릭한다.

3-8-2. 외부 IP 주소를 클릭한다

3-8-3. IP유형을 고정으로 변경한다

3-9. 이제 설정은 끝났다. 서버에 접속해 보도록 하자.
ssh 터미널 접속은 VM 인스턴스 화면에서 ssh터미널을 클릭하면 된다.

sftp 접속은 별도로 filezilla ftp client를 설치해서 진행해야 된다.
파일질라 설치 후 사이트 관리자에서 아래와 같이 설정한다.
키 파일은 이전에 생성한 test.ppk를 넣으면 된다.

4. Nginx + Nodejs 설치는 쉽게 검색할 수 있을 것이다
여기서는 주의할 사항과 참고할 설정파일을 올린다.

4-1. 주의사항
Nginx 설치 후 웹브라우저로 접속해보면 접속이 안될 것이다.
당황하지말고 방화벽을 확인한다.
1차로 확인해 봐야 되는 내용은 google cloud의 방화벽 규칙이다
80,443 포트에 대한 inbound 규칙이 들어가 있는지 확인한다

2차로 가장 어이없는 부분이다.
Google Cloud의 Ubuntu 서버는 iptables 설정도 별도로 해줘야된다
ssh 터미널에서 80,443 포트에 대한 허용을 해준다.

sudo iptables -A INPUT -p tcp –dport 80 -m recent –set –name HTTP_Flood
sudo iptables -A INPUT -p tcp –dport 80 -m recent –update –seconds 1 –hitcount 25 –name HTTP_Flood -j LOG –log-prefix “[Flood Attack Detected]”
sudo iptables -A INPUT -p tcp –dport 80 -m recent –update –seconds 1 –hitcount 25 –name HTTP_Flood -j DROP
sudo iptables -A INPUT -p tcp –dport 443 -m recent –set –name HTTPS_Flood
sudo iptables -A INPUT -p tcp –dport 443 -m recent –update –seconds 1 –hitcount 25 –name HTTPS_Flood -j LOG –log-prefix “[Flood Attack Detected]”
sudo iptables -A INPUT -p tcp –dport 443 -m recent –update –seconds 1 –hitcount 25 –name HTTPS_Flood -j DROP
sudo iptables –list

4-2. Nginx 설정파일
참고로 필자는 실제 도메인인 arlapras.com 을 사용하고,
서버에 SSL 인증서를 적용했다.
이렇게 설정하면 Nginx가 Proxy서버이기 때문에 하위에 있는 nodejs 서버들은
자동으로 SSL 인증이 된다.

/etc/nginx/sites-enabled/default
#Standalone Websocket Server (Thin)
upstream web_server {
server 127.0.0.1:6001;
}
upstream wss_server {
server 127.0.0.1:6002;
}
#HTTP Server
server {
listen 80 default_server;
server_name arlapras.com http://www.arlapras.com;
return 301 https://$host$request_uri;
}
#HTTPS Server
server {
listen 443 ssl;
server_name arlapras.com http://www.arlapras.com;
root /var/www/html;
# SSL Credentials
ssl_certificate /etc/nginx/ssl/unified.www.arlapras.com.pem;
ssl_certificate_key /etc/nginx/ssl/www.arlapras.com_201910177BW8.key.pem;
# websocket_rails uses the ‘/websocket’ route
location / {
proxy_pass http://wss_server;
proxy_http_version 1.1; # use http/1.1 version protocol translation mechamism
proxy_set_header Upgrade $http_upgrade; # hop-by-hop
proxy_set_header Connection “upgrade”; # hop-by-hop header
proxy_set_header Origin “”;
}
}

1 comment

댓글 남기기

이 사이트는 스팸을 줄이는 아키스밋을 사용합니다. 댓글이 어떻게 처리되는지 알아보십시오.

%d 블로거가 이것을 좋아합니다: