프로그래머...

필고 개발자그룹에서는
필리핀에 계시는 개발자분들이 함께 성장 할 수 있는 공간입니다.

정모: 11월 1일
Image at ../data/upload/7/1203907Image at ../data/upload/4/1112674Image at ../data/upload/2/1046612Image at ../data/upload/9/838729Image at ../data/upload/6/820796Image at ../data/upload/9/766049Image at ../data/upload/0/766040Image at ../data/upload/5/746745
Sub Page View
Today Page View: 4
Yesterday View: 1
30 Days View: 301
Image at ../data/upload/3/2288953

화상 통화 시스템 개발 프로젝트 Video Call System Development Project(1)

Views : 12,161 2013-09-08 15:21

QR 스캔해주세요.
필고 개발자 그룹 1269544315
Report List New Post

화상 통화 시스템 개발 프로젝트 Video Call System Development Project

HTML5 WebRTC 강좌

서문

요약

HTML5

WebSocket

Node.js

WebRTC

참고 문서

MedieaStream(GetUserMediea) : 카메라 열기

다른 사용자와 영상 통화

TURN 서버

자료

설치 전 준비

libevent2 설치

설치 문서

설치 : 소스컴파일 설치

설정

실행

동작 확인

방화벽 열기

설치 후

참고 문서

미디어 통신의 이해

서문

작성자 : 송재호

저작권 : 본 문서의 저작권은 없습니다. 누구든지 어떤 용도로든지 마음데로 사용 할 수 있습니다.

안내문 : 본 문서는 필리핀 정보 사이트 “필고”의 웹 개발자 카페 강좌를 위해서 작성하는 것입니다. 본 문서는 구글 드라이브를 통해서 실시간으로 공개됩니다. 최신의 버젼을 확인하기 위해서는 이 곳을 (“화상 통화 시스템 개발 프로젝트”) 클릭하십시오.

요약

나에게 프로그래머 특유의 기질이 있음을 부정해 왔습니다. 지난 수십년간 컴퓨터에 미친놈으로 비쳐져 왔지만 정작 본인은 이를 강하게 부정하면서 살아왔습니다.

여러분이 프로그래머로서 길을 걷고 있다면 그 길을 멈추는 날 까지 끝 없이 고행을 해야 한다는 것을 스스로 느끼 실 것입니다.

본 프로젝트를 시작하면서 저에게 프로그래머로서 서로 화합을 할 수 있는 시간이 바로 지금 일 것입니다. 화상 통화 시스템 개발은 쉬운 일이 아닙니다. 지금까지 수 많은 과학자와 개발자의 헌신으로 버튼 하나만 누르면 멀리는 가족이나 친구와 화상 통화를 할 수 있습니다. 그 분들의 너무나 큰 노고를 생각하면 본 프로젝트를 알차게 진행해야겠다는 생각이 듭니다.

우리는 또 다른 혁신의 꿈틀거림을 보고 있습니다.

그것은 바로 HTML5 입니다. 우리는 HTML5 를 통해서 화상 통화 시스템을 개발 할 것입니다.

본 문서는 화상 통화 시스템 개발을 위한 HTML5 의 WebRTC 강좌라고 보셔도 됩니다.

안타깝고 죄송스럽지만 본 문서에 기초부터 차근 차근 설명을 하지 않습니다. 본 문서는 고급자를 대상으로 합니다. 직접 C++ 언어 등으로 서버/클라이언트 프로그래밍을 해 본 경험이 있고 게임 서버를 직접 만들어 본 경험이 있는 대상자를 바탕으로 합니다.

그렇다고 고급자를 대상으로 한다고 해서 너무 주눅들지는 마십시오. HTML 이 기껏해 봐야 거기서 거기지 않겠습니까?

문서를 편집하면서 존칭을 생략합니다. 양해 부탁드립니다.

HTML5

HTML 에 대해서 공부 해 본 적이 있는가? 그렇다면 HTML5 의 Storage 와 Connectivity 에 대해서 구체적인 설명과 예제 코드를 작성 할 수 있는가?

HTML5 에는 파일이나 데이터베이스 이용에 대한 구체적인 (표준적인) 규약이 있다. 과거에는 상상이나 했을까? 자바스크립트로 직접 DB 에 쿼리를 하고, 파일을 액세스하는 그런 일은 보안상의 이유로 철두 철미하게 막았다. 자바애플릿 시절에도 파일 액세스는 불가 했다.

하지만 이제 힘들고 어두운 시대는 사라졌고 새 시대가 도래했다. 세상이 바뀌었다. 이러한 새 세상에서 프로그래머는 선구자 역활을 해야 한다.

여러분은 선구자인가?

지금이라도 HTML5 에 대해서 배우라. 본 프로젝트를 위해서 우리가 필요로 하는 부분은 바로 HTML5 Connectivity 이다.

필고 웹 개발자 그룹에서 그러한 정보를 찾으시면 된다. http://www.philgo.com

WebSocket

자바스크립트를 통해서 서버와 소켓 통신을 할 수 있도록 해 준다.

http://blog.naver.com/davincigo?Redirect=Log&logNo=60196246436

http://blog.naver.com/winipe?Redirect=Log&logNo=150161799781

Node.js

요즘 날리고 있는 프로그래밍 패러다임이다.

http://www.nodebeginner.org/index-kr.html

http://nodejs-kr.org/insidejs/

WebRTC

우리가 사용 해야 할 것이 바로 WebRTC 이다.

현재 HTML5 가 그렇듯 HTML5 에 속한 모든 것이 정식 버젼이 아니다. HTML5 은 약 10년 전 부터 꾸준히 개발되어져 왔지만 아직 정식 버젼으로 채택되려면 많은 시간이 남았다. (적어도 1년 이상은 더 기다려야 할 것 같다.)

WebRTC 는 Web Real-Time Communication 의 약자로 웹 브라우저간에 서로 통신을 할 수 있는 기술이다. 특징으로서는 웹브라우저가 외부 프로그램의 도움 없이 오로지 웹브라우저 기능만으로 P2P 통신을 하는 것이다. (물론 꼭 P2P 에 제한 된 것은 아니다.)

따라서 기존의 웹브라우저로는 안되며 WebRTC 기능을 포함한 웹 브라우저라야만 하는 것이다.

현재 크롬과 파이어폭스가 WebRTC 를 지원하고 있다.

WebRTC 는 구글이 처음 오픈소스로 선보였으며 이후 국제 인터넷 표준화 기구가 프로토콜 표준화 작업을 하고  W3C 가 API 표준화 작업을 하였다.

참고 문서

WebRTC 의 정식 사이트는 http://www.webrtc.org 이다.

본인이 WebRTC 를 공부하면서 가장 도움이 된 것이 바로 http://dev.w3.org/2011/webrtc/editor/webrtc.html

http://www.html5rocks.com/en/tutorials/webrtc/basics/?redirect_from_locale=ko#toc-support

https://bitbucket.org/webrtc/codelab

MedieaStream(GetUserMediea) : 카메라 열기

우선 웹 브라우저에 카메라 부터 열어보자. GetUserMedia 라는 API 로 가능하다.

소스코드는 아래와 같다.

<!doctype html>

<html>

<head>

</head>

<body>

<video />

<script>

navigator.getUserMedia = navigator.getUserMedia ||  navigator.webkitGetUserMedia || navigator.mozGetUserMedia;

var constraints = {video: true};

function successCallback(localMediaStream) {

window.stream = localMediaStream; // stream available to console

var video = document.querySelector("video");

video.src = window.URL.createObjectURL(localMediaStream);

video.play();

}

function errorCallback(error) {  console.log("navigator.getUserMedia error: ", error); }

navigator.getUserMedia(constraints, successCallback, errorCallback);

</script>

</body>

</html>

웹 브라우저로 열면 아래와 같은 모습을 볼 수 있다.

(사진: 웹브라우저에서 카메라를 연 모습. Chrome 이나 Firefox 최신 버젼으로 테스트를 할 수 있다. )

소스는 비교적 간단하다.

local media stream 을 통해서 카메라로 들어오는 영상을 video 태그에 넣어 주는 것이다.

다른 사용자와 영상 통화

소스는 아래와 같다.

<!DOCTYPE html>

<html>

   <head>

       <script src="simplewebrtc.com/latest.js"></script>

   </head>

   <body>

       <div id="localVideo"></div>

       <div id="remotesVideos"></div>

<script>

var webrtc = new SimpleWebRTC({

   // the id/element dom element that will hold "our" video

   localVideoEl: 'localVideo',

   // the id/element dom element that will hold remote videos

   remoteVideosEl: 'remotesVideos',

   // immediately ask for camera access

   autoRequestMedia: true

});

// we have to wait until it's ready

webrtc.on('readyToCall', function () {

   // you can name it anything

   webrtc.joinRoom('jaeho');

});

</script>

   </body>

</html>

SimpleWebRTC API 를 사용했으며 기본적으로 google STUN 서버를 이용한다.

실제로 위 소스코드를 테스트 해 본 결과 에코가 조금 발생하고 있는 것을 확인했다.

물론 본 프로젝트에서는 직접 많은 부분을 작성 할 것이다.

직접 API 를 작성하고 STUN 서버를 설치 할 것이다.

TURN 서버

여러분들이 다 알겠지만 TURN 서버는 중계서버로서 따로 설명이 필요없는 일반적인 개념이며 네트워크 프로그래머라면 이미 알고 있는 것이다. 파이어월 등으로 인해서 P2P 가 불가능 할 때 TURN 서버가 데이터를 중계해 준다.

2013년 현재 구글이 배포하는 https://code.google.com/p/rfc5766-turn-server/ 와 restund http://www.creytiv.com/pub/ 를 선택 할 수 있다.

둘다 활발히 개발 중인 오픈소스이다.

본 프로젝트에서는 구글 오픈 소스를 사용하기로 결정을 했다.

거의 모든 TURN 서버는 STUN 서버의 기능을 내장하고 있다. 따라서 TURN 서버를 설치한다는 것은 STUN 서버를 포함하는 것이다.

구글 TURN 서버 홈페이지에 들어가면 PDF 로 된 문서와 각종 case study 에 대한 링크가 있다.

설치는 비교적 쉽다. 구글의 TURN 서버를 만들때 첫번째 목표가 바로 쉬운 설치이기 때문이다.

자료

TURN 서버에 대한 재미있는 자료를 인터넷 상에서 발견하였다. http://purematter.blog.me/110102481519

설치 전 준비

openssl-devel 과 libevent2 를 설치해야 한다.

# yum install openssl-devel

# yum remove libevent

libevent2 설치

$ wget github.com/downloads/libevent/libevent/libevent-2.0.21-stable.tar.gz

$ tar xvf libevent-2.0.21-stable.tar.gz

$ cd libevent-2.0.21-stable

$ ./configure --prefix=/usr

$ make

$ make install

$ /sbin/ldconfig

설치 문서

https://code.google.com/p/rfc5766-turn-server/downloads/detail?name=INSTALL&can=2&q=

설치 : 소스컴파일 설치

# wget https://rfc5766-turn-server.googlecode.com/files/turnserver-2.6.2.1.tar.gz

# tar xzf turnserver-2.6.2.1.tar.gz

# cd turnserver-2.6.2.1

# ./configure

# make

# make install

설정

기본적으로 /ur/local/etc 가 설정 디렉토리가 된다.

# cd /usr/local/etc/

# # cp turnuserdb.conf.default turnuserdb.conf

# vi turnuserdb.conf

아래 라인을 추가한다.

my_username:my_password

실행

물론 아래의 명령 중에서 여러분의 설정에 맞도록 적절하게 입력을 해야 한다.

# turnserver -L 192.168.1.35 -a -b turnuserdb.conf -f -r workserver.org

동작 확인

# netstat -ap | grep LISTEN

tcp        0      0 192.168.1.35:stun           *:*                         LISTEN      11616/turnserver

# cat /etc/services | grep stun

방화벽 열기

3478 (STUN) 포트를 연다.

[root@workserver ~]# vi /etc/sysconfig/iptables

아래 라인을 추가

-A INPUT -m state --state NEW -m tcp -p tcp --dport 3478 -j ACCEPT

-A INPUT -m state --state NEW -m udp -p udp --dport 3478 -j ACCEPT

[root@workserver ~]# service iptables restart

iptables: Flushing firewall rules:                         [  OK  ]

iptables: Setting chains to policy ACCEPT: filter          [  OK  ]

iptables: Unloading modules:                               [  OK  ]

iptables: Applying firewall rules:                         [  OK  ]

[root@workserver ~]# iptables -L | grep stun

ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:stun

ACCEPT     udp  --  anywhere             anywhere            state NEW udp dpt:stun

설치 후

설치를 하면 시스템이 부팅을 할 때 자동으로 실행되게하는 방법이 설명된다.

자동으로 하지 않을 때에는 적절한 옵션과 함께 turnserver 를 실행하면 된다고 한다.

본인의 스타일은 적절한 옵션과 함께 /etc/rc.d/rc.local 과 같은 파일에 추가를 하는 것이다.

다음과 같이 turnserver 파일의 정보를 확인 했다.

# file $(which turnserver)

$ man turnserver

$ man turnadmin

$ man turnutils

참고 문서

Extra Doc 문서에 아래의 두개 문서를 참고한다.

TURNServerRESTAPI.pdf

TurnNetworks.pdf

미디어 통신의 이해

본 장에서 local 은 호출하는 클라이언트고 remote 는 호출 받는 클라이언트이다.

RTCPeerConnection 의 연결 순서는

통신을 위한 채널(ROOM)에서 기다리는 클라이언트의 경우 Offer 수신 -> PeerConnection 생성 -> Answer 송신 순서로 연결을 한다.

ROOm에 들어가는 클라이언트는 PeerConnection 생성 -> Offer 송신 -> Answer 수신으로 연결을 한다.

PeerConnection 이 생성되고 Local Description 이 설정되면 ICE 가 동작한다.

  1. 처음 시작을 위한 준비는 getUserMedia 를 통해서 현재 컴퓨터의 MediaStream 을 얻는 것이다.
    각 브라우저 마다 구현이 틀리니 adapter.js 를 참고한다.
    getUserMedia({audio:true, video:true}, gotStream, function(error) { trace("navigator.getUserMedia error: ", error); });
    와 같이 해서 사용자의 웹 브라우저에서 audio, video stream 을 얻는다.
    gotStream() callback 에서는 <VIDEO> 태그의 src 속성에 localVideo.src = URL.createObjectURL(stream); 와 같이 해서 비디오를 연결한다.

  2. 호출을 시작 할 때, localPeerConnection 객체를 만든다. 각 웹브라우저마다 구현 방법이 틀리므로 adapter.js 를 참고한다.
    local 과 remote 모두 만들어야 한다. (물론 하나만 만들 수도 있겠지만)

  3. 생성된 localPeerConnection 에 onicecandidate 에 콜백으로 ice candidate 가 만들어 질 때, remotePeerConnection 에 연결한다.

  4. remotePeerConnection 을 만들고 마찬가지로 onicecandidate 에 콜백으로 원격 컴퓨터의 ice candidate 가 만들어 질 때, localPeerConnection 에 연결한다.

  5. localPeerConnection.addStream(localStream) 와 같이 해서 localStream 을 localPeerConnection 으로 연결한다.

  6. 그리고 localPeerConnection 에서 createOffer() 를 통해서 SDP 를 생성한다. SDP 가 만들어지면 callback 이 실행되는데, 그 callback 안에서 아래와 같이 setLocalDescripition 에 SDP 를 설정해야한다. 그리고 아래에서는 로컬 SDP 가 생성될 때, 원격의 peer 에서 바로 createAnswer() 를 통해서 응답을 해 버린다. 이것은 하나의 페이지에서 두개의 클라이언트가 모두 실행되기 때문이다.
    function gotLocalDescription(description){
       localPeerConnection.setLocalDescription(description);
       trace("Offer from localPeerConnection: n" + description.sdp);
       remotePeerConnection.setRemoteDescription(description);
       remotePeerConnection.createAnswer(gotRemoteDescription);
    }

  7. 원격 peer 의 SDP 가 만들어지면 마찬가지로 setLocalDescription 에 지정을 해 준다. 그리고 상대 peer 에 setRemoteDescription 을 해 준다.

  8. Offer 와 Answer 를 통해서 ICE 작업을 할 때,
    onicecandidate 에 연결된 콜백 함수에서,
    localPeerConnection.addIceCandidate(new RTCIceCandidate(event.candidate));
    와 같이 연결을 해 주어야 한다.

  본 글을 신고하시겠습니까?
Report List New Post
거기서살고싶다 [쪽지 보내기] 2015-02-18 11:11 No. 1270261697
html5 개발이 조금 간편하기는 하지만 그전 ie7,8은 버릴수 없어 결국 flex나 기타 플러그인이 들어가야 하는데.. 8,9 websocket를 지원받을수 없습니다. 단순 10이상의 브라우저만 대상으로 하는 것인지??
기존 개념 공부를 하기 위한 방법인지? 
필고 개발자 그룹
No. 95
Page 3
권오창@페이스...  3224  19-04-07
만강이  2859  15-08-31
Photo Post thumbbail image
whizenglish  4309  15-06-20
Post thumbnail image
whizenglish  7195  15-05-21
커먼웰쓰  3478  15-05-14
바다디다  2591  15-02-21
dnfkfkfkfkf  3464  15-01-25
필고관리자  2991  15-01-03
Post thumbnail image
필고관리자  9941  15-01-03
굿리  3395  15-01-02
요잇  3259  14-12-11
jeremyPark  3053  14-12-03
Post thumbnail image
thruthesky  39685  14-09-30
필고관리자  3444  14-09-30
오늘도잠온다  3776  14-05-03
오늘도잠온다  3375  14-04-07
필고관리자  4233  14-01-15
thruthesky  10564  14-01-11
thruthesky  5611  13-12-22
Post thumbnail image
thruthesky  6819  13-12-16
thruthesky  10267  13-11-26
thruthesky  3825  13-11-24
thruthesky  2184  13-11-10
thruthesky  2557  13-11-10
thruthesky  4845  13-11-10
thruthesky  3689  13-11-10
thruthesky  2698  13-09-29
Post thumbnail image
thruthesky  7972  13-09-28
Post thumbnail image
thruthesky  10947  13-09-28
오늘도잠온다  4605  13-09-27
오늘도잠온다  2133  13-09-27
Photo Post thumbbail image
필고관리자  10219  13-09-21
thruthesky  2790  13-09-15
Photo Post thumbbail image
thruthesky  5835  13-09-12
Photo Post thumbbail image
thruthesky  2574  13-09-11
Photo Post thumbbail image
thruthesky  12933  13-09-10
Photo Post thumbbail image
thruthesky  12162  13-09-08
Photo Post thumbbail image
thruthesky  5245  13-09-07
thruthesky  3951  13-09-03
깜씨  3561  13-09-02