2014년 3월 27일 목요일

[튜토리얼/한글화] WebRTC 시작하기(Getting started with WebRTC)

HTML5Rocks에 +Sam Dutton의 'WebRTC 시작하기(Getting Started With WebRTC)' 튜토리얼의 한글 버전이 업데이트되었습니다. 이번 번역은 이원제(+nuri nam)님께서 수고해주셨습니다. :)

"말그대로 WebRTC는 웹을 위한 실시간 통신 규격입니다. 이는 오디오나 비디오 스트림을 P2P로 송수신하는 것뿐만이 아니라 데이터 전달을 위한 메커니즘을 포함하고 있습니다. 대다수의 서비스들은 클라언트-서버 간의 데이터 통신을 통해 기능을 제공하고 있지만 어떤 경우는 클라이언트 간의 빠른 데이터 교환이 주요 기능 구현 사항이 되기도 합니다. 바로 이러한 경우 WebRTC는 중요한 기반 기능을 제공합니다. 뒤집어 얘기하자면 서버를 중계할 이유가 없으며 클라이언트 간의 데이터를 빠르게 송수신하고자 한다면 WebRTC는 좋은 선택이 될 수 있습니다. WebRTC의 다양한 구현 사례를 보기 전에 이 튜토리얼을 통해 WebRTC가 어떠한 것이고 어떻게 사용하는지를 확인해보시기 바랍니다."


TL;DR;


현재 웹의 주요 도전 과제 중에 남은 하나는 실시간 대화(Real Time Communication, RTC) 가능하게 하는 것입니다. 많은 웹서비스들이 이미 실시간 통신을 사용하고 지만 네이티브 앱이나 플러그인들의 다운로드가 필요했습니다. 이제 HTML5에서 플러그인 없는 실시간 통신을 위한 규격인 WebRTC는 현재 크롬, 오페라, 파이어폭스에서 가능하며 WebKitGTK+ 와 Qt 네이티브 프레임워크에도 통합되어 있습니다.

WebRTC 어플리케이션이 취하는 일반적인 기능은 다음과 같습니다.

  • 스트리밍 오디오, 비디오 또는 데이터의 획득
  • 네트워크 정보의 획득 및 다른 WebRTC 클라이언트들과 정보 교환
  • 에러들의 보고, 세션 초기화/종료를 위한 Signal 통신 관리
  • 미디어와 클라이언트의 지원 기능(해상도와 코덱 등)에 대한 정보 교환
  • 스트리밍 오디오, 비디오, 데이터의 송수신



apprtc.appspot.com의 WebRTC 통신 및 일반 통신

스트리밍 데이터를 얻고 통신하기 위해 WebRTC에서는 다음과 같은 API를 제공합니다.

  • (getUserMedia라고도 하는) MediaStream - 카메라/마이크 등 데이터 스트림 접근
  • RTCPeerConnection - 암호화 및 대역폭 관리 및 오디오 또는 비디오 연결
  • RTCDataChannel - 일반적인 데이터 P2P통신


> MediaStream


MediaStream API는 미디어의 동기화된 스트림들을 말합니다. 예를 들어, 카메라와 마이크의 입력에서 받아온 스트림은 오디오와 비디오 트랙들로 동기화 됩니다. getUserMedia()는 반드시 로컬 파일 시스템이 아닌 서버에서 사용되어야 합니다.


> 시그널링(Signaling)


WebRTC 클라이언트로 사용되는 웹 브라우저들 사이에 스트리밍 데이터를 주고 받기 위해 RTCPeerConnection를 사용하며 통신을 조율하고 조장할 메세지를 주고 받기 위해 시그널링(Signaling)으로 알려진 일련의 과정이 필요합니다. 시그널링(Signaling)은 RTCPeerConnection API에 포함되지 않지만 WebRTC 개발자들은 SIP, XMPP 또는 적절한 쌍방통신 채널 등 자신들에게 편한 방식을 선택할 수 있습니다.


> RTCPeerConnection


RTCPeerConnection은 Peer들 간의 데이터를 안정적이고 효율적으로 통신하게 처리하는 WebRTC 컴포넌트입니다. JavaScript 측면에서 보면 RTCPeerConnection는 WebRTC에서 사용되는 엄청나게 많은 일들을 개발자가 신경쓰지 않을 수 있도록 많은 기능을 백그라운드에서 지원하고 있습니다. 실제로 WebRTC는 서버가 필요하지만 단순합니다.


> RTCDataChannel


오디오와 비디오처럼, WebRTC는 실시간으로 다른 형태의 데이터 통신도 지원합니다. RTCDataChannel API는 피어와 피어간 임의의 데이터 교환을 빠른 반응속도와 높은 처리량으로 가능하게 합니다. 이 API를 이용하여 게임이나 원격 데스크탑 어플리케이션, 실시간 채팅, 파일 전송, 분산 네트워크 등으로의 응용이 가능합니다.

RTCDataChannel API는 RTCPeerConnection의 대부분의 기능들을 활용하여 강력하고 유연한 P2P통신을 가능하게 하는 몇가지 기능을 가지고 있으며 통신은 브라우저간 직접 연결됩니다 , 그래서 RTCDataChannel은 WebSocket보다 매우 빠릅니다. 심지어 방화벽과 NAT의 방해로 '구멍내기'가 실패하여 중계(TURN) 서버와 연결이 되더라도 빠릅니다.


> 보안


실시간 통신 어플리케이션이나 플러그인에서 보안 문제가 발생하는 경우가 몇가지가 있습니다. WebRTC는 이 문제들을 피할 수 있는 몇가지 기능들을 가지고 있습니다:


  • WebRTC는 DTLS와 SRTP등의 보안 프로토콜을 사용하여 구현되었습니다. 따라서 암호화는 Signlaing 메커니즘을 포함한 모든 WebRTC Components의 필수 조건입니다.
  • WebRTC는 플러그인이 아니므로 컴포넌트들은 브라우저의 샌드박스위에서 실행되고 별도의 프로세스로 나눠지지 않습니다.
  • 카메라와 마이크에 접근은 반드시 허가를 통합니다.


WebRTC에 대한 자세한 내용은 튜토리얼을 참조하시기 바랍니다.

번역 링크


참조 링크

[튜토리얼/한글화] HTML5에서 오디오 및 비디오 캡쳐하기(Capturing Audio & Video in HTML5)

HTML5Rocks에 +Eric Bidelman의 'HTML5에서 오디오 및 비디오 캡쳐하기(Capturing Audio & Video in HTML5)' 한글 튜토리얼이 업데이트되었습니다.

그동안 웹에서 오디오와 비디오의 캡쳐는 재생과는 전혀 다른 범주의 기능처럼 인식되어 왔습니다. HTML5는 다른 많은 기능과 마찬가지로 오디오 및 비디오의 재생뿐만이 아니라 오디오나 비디오 입력 스트림의 처리를 가능하도록 그 기능을 확장하였습니다. 이 튜토리얼은 이 기능들을 다루기 위한 기초적인 설정 방법부터 몇가지 일반적인 구현 사례를 설명합니다.

이번 번역은 이원제(+nuri nam)님께서 수고해주셨습니다. :)

"오랜 기간동안 웹 환경은 개발자에게 플래시나 실버라이트와 같은 플러그인을 이용하여 오디오와 비디오 캡쳐를 구현하도록 강요해왔습니다. HTML5는 이러한 플러그인 종속성을 없애고 이들 장치에 대한 입력 스트림을 직접 제어할 수 있도록 기능을 제공하고 있습니다. 입력 스트림을 제어한다는 것은 여러분의 웹 앱을 생각보다 더 크게 확장할 수 있습니다. WebRTC의 일반적인 사례처럼 비디오 컨퍼런스 서비스를 구현할 수도 있지만 조금만 더 아이디어를 덧붙인다면 네이티브에서 구현해왔던 얼굴/모션의 검출 등으로 얼마든지 확장할 수 있습니다."



TL;DR;


지난 세월동안 오디오와 비디오 캡쳐는 외부 플러그인들을 사용할 수 밖에 없었습니다. HTML5는 다양한 하드웨어에 대한 접근을 표준 규격으로 정의하고 있으며 오디오와 비디오의 캡쳐 역시 예외는 아닙니다. 이와 관련해서 그동안 다양한 규격들이 W3C에서 시도되어 왔지만 현재 getUserMedia()를 통해 대다수의 작업을 할 수 있도록 정리되었습니다. 이제 여러분은 getUserMedia()를 통해 사용자의 카메라와 마이크를 웹앱에서 접근할 수 있습니다.

> 멀티미디어 디바이스의 접근


사용자의 멀티미디어 디바이스의 입력 스트림을 제어하기 위해서 다음과 같은 기능들이 필요할 것입니다.


  • 미디어에 대한 권한 요청
    • 웹캠과 마이크에 접근하기 위해서는 먼저 어떤 디바이스에 어떠한 방식으로 접근하는지에 대한 권한을 getUserMedia()를 이용하여 요청해야 합니다.
  • 미디어 기능 요구사항 설정
    • 필요하다면 getUserMedia()의 호출 시 접근하고자 하는 미디어 스트림에 대해 필요한 요구사항들(해상도, 비트레이트 등)을 설정할 수 있습니다.
  • 미디어 소스의 검색과 선택
    • 크롬의 경우 버전 30 이후부터는 getUserMedia()에서 입력 스트림으로 사용가능한 소스를 검색할 수 있도록 MediaStreamTrack.getSources() API를 지원합니다.
    • 이 API를 이용하면 현재 디바이스에 지원하고 있는 접근 가능한 입력 스트림 소스에 대한 리스트를 액세스할 수 있으며 이를 통해 적합한 디바이스를 선택할 수 있습니다.


getUserMedia()를 사용할 때 일부 브라우저는 카메라와 마이크에 대한 접근에 대한 사용자 허가를 요청하는 상태바를 표시할 수 있으며 getUserMedia()가 지원되지 않거나 API 호출이 실패하였을때 다른 형태의 미디어로 대체하는 과정이 필요할 수 있습니다.


> 입력 스트림을 통한 몇가지 구현 사례들

디바이스의 입력 스트림에 성공적으로 접근한 뒤에 <video>나 <audio> 태그의 소스로 사용할 수도 있지만 이를 통해 다음과 같이 추가적인 기능을 구현할 수도 있습니다.


  • 사진 찍기
    • <canvas> API의 ctx.drawImage()를 이용하여 입력 스트림을 정적인 사진 이미지 형태로 활용하여 사진 촬영 기능으로 사용할 수 있습니다.
  • 효과 적용
    • CSS Filters를 사용해서 <video>에 대한 효과를 적용할 수 있습니다.
    • 비디오 스트림을 WebGL Texture로 이용할 수 있습니다.
    • 크롬의 경우 getUserMedia()의 스트림을 Web Audio API로 연결하여 오디오를 직접 제어할 수 있습니다.


이제 웹앱의 범주를 확장하기 위한 다양한 시도들 중의 하나인 getUserMedia()를 이용하여 다양한 어플리케이션의 개발을 시도해보시기 바랍니다. 자세한 내용은 튜토리얼을 참조하세요.



번역 링크

참고 글


2014년 3월 7일 금요일

[튜토리얼/한글화] 자바스크립트 성능 수수께끼를 해결하기 위한 과학적인 검출 방법 사용하기(Use forensics and detective work to solve JavaScript performance mysteries)

HTML5Rocks에 +John McCutchan의 '자바스크립트 성능 수수께끼를 해결하기 위한 과학적인 검출 방법 사용하기(Use forensics and detective work to solve JavaScript performance mysteries)' 한글 튜토리얼이 업데이트되었습니다.

당연한 얘기지만 모든 최적화는 문제가 되는 지점을 개선하는 작업입니다. 당연한 얘기겠지만 이러한 이유로 성능 병목 지점을 찾는 것이 가장 첫번째 단계입니다. 문제의 원인을 찾으면 여러가지 테크닉 중 어떤 것을 선택해서 해결할 수 있는지에 대한 방법을 결정할 수 있을 것입니다. 이 튜토리얼은 Find Your Way to Oz의 개발 과정에서 성능 문제를 개선하기 위해 병목 지점들을 찾는데 사용된 방법을 다루고 있는 사례 연구이기도 하며 실질적인 가이드라인이기도 합니다.

이번 번역은 +Jae-Hoon Kim님께서 수고해주셨습니다. GDG Seoul 2월 밋업에서의 발표 후 얼마 안되서 바로 참여해주셨는데 감사드립니다. :)

"가비지 콜렉션이나 로직 오버헤드, 렌더링 오버헤드  혹은 리소스 로딩으로 인한 jank 등 하나의 어플리케이션에서 성능에 영향을 주는 요인은 굉장히 많습니다. 점진적으로 하나씩 개선해나가는 방식도 좋지만 가능하다면 가장 큰 요인 중 가장 쉽게 해결할 수 있는 것들부터 찾아나가거나 다른 기준에 의해 성능을 개선할 수도 있을 것입니다. 만약 이러한 방식을 원하신다면 그 무엇보다도 우선시되어야 할 작업은 최적화가 아닌 진단입니다."



TL;DR;


최근 몇 년 동안 자바스크립트 가상 머신 기술의 놀라운 진보에도 불구하고, 최근 한 연구는 Google 어플리케이션이 그들의 시간 중 50~80%를 V8에서 보내고 있음을 증명하였습니다. CPU 사이클은 하나의 제로-썸 게임입니다. 시스템 리소스를 더 적게 사용하도록 하는 것은 더 높은 성능을 보여주는 방법이며 고성능 실시간 어플리케이션에서 무엇보다 중요합니다.

성능 문제를 해결하는 것은 범죄를 해결하는 것과 유사합니다. 여러분은 조심스럽게 증거를 조사하고 의심되는 원인들을 확인하고 다른 해결책들을 실험하는 것이 필요합니다. 이러한 과정 내내 문제를 실제로 고쳤는지 확인할 수 있도록 반드시 측정된 결과들을 문서화해야 합니다.

이 튜토리얼은 Find Your Way to Oz의 모호한 성능 문제를 찾아내고 자바스크립트를 최적화와 프로파일링한 방법들을 다루고 있습니다. Oz의 경우 가설을 통해 최종적으로 선택된 두 개의 용의자가 있었으며 이를 V8 엔진의 로그와 V8 내부의 최적화에 관련된 추적을 통해 정확한 문제점을 도출하고 자바스크립트 for-in 구문의 수정을 통해 성능을 개선하였습니다.

> 자바스크립트의 로그를 이용한 성능 요인 검출 방법


V8 자바스크립트 엔진은 내장된 로깅 시스템을 가지고 있습니다.

터미널에서 "--no-sandbox --js-flags="--prof --noprof-lazy --log-timer-events" 인자들을 이용하여 크롬을 실행하고 어플리케이션을 구동한 뒤 종료하면 현재 디렉터리 안에 v8.log 파일이 생성됩니다. 이렇게 생성된 로그는 tick processor와 plot-timer-event를 통해 분석할 수 있습니다.


> V8 최적화의 추적


V8의 자바스크립트 성능 관련 팁들에서 언급된 바 있듯이 V8은 높은 성능을 위해 실행 시간에 자바스크립트에 대한 많은 최적화를 수행합니다. 만약 이 과정에서 의심되는 문제가 있다면 터미널에서 "--js-flags="--trace-deopt --trace-opt-verbose" 인자를 통해 크롬을 실행하여 상세 로그를 확인할 수 있습니다.


자세한 내용은 튜토리얼을 참조하시기 바랍니다.


번역 링크

참고 글

[튜토리얼/한글화] 여러분의 Gruntfile을 강력하게: 빌드 설정 쥐어짜기(Supercharging your Gruntfile: How to squeeze the most out of your build configuration)

HTML5Rocks에 +Paul Bakaus의 튜토리얼 'Gruntfile을 강력하게: 빌드 설정 쥐어짜기(Supercharging your Gruntfile: How to squeeze the most out of your build configuration)'의 한글 버전이 업데이트되었습니다.

Node.js가 등장한 이후 이를 이용한 다양한 모듈과 서비스들 쏟아져 나왔습니다. 아마 Ben Alman이 만든 Grunt 역시 그 중의 하나이며 가장 사랑받는 모듈 중의 하나일 것입니다. Grunt는 프론트엔드 웹 개발 및 배포 환경의 많은 부분을 자동화할 수 있도록 강력한 빌드 기능을 제공합니다. 특히 JavaScript를 통해 이러한 부분이 제어될 수 있다는 점 역시 프론트엔드 개발자들에게 Grunt가 사랑받는 이유 중의 하나일 것입니다.

그러나 대부분의 프론트엔드 개발 프로젝트는 강력해진 기능만큼이나 복잡한 개발 및 테스트, 배포 환경을 필요로 하게 되었고 부피가 커진 만큼이나 다루기가 어려워져 가고 있습니다. Grunt도 이 부분에서는 예외가 아닙니다.

이 튜토리얼은 프로젝트가 커질 수록 더 유용해지는 몇가지 Grunt 플러그인들과 Grunt의 빌드 프로세스 자체를 개선할 수 있는 핵심적인 내용을 살펴볼 것 입니다.


"Grunt는 개발자가 커스터마이징할 수 있는 강력한 빌드 환경을 제공합니다. 하지만 복잡하고 거대해진 프로젝트 빌드 환경을 관리하는 것은 프로그래밍과는 또다른 영역의 작업들을 수반합니다. Gruntfile을 얼마나 깔끔하게 관리할 수 있는지, 빌드를 얼마나 신속하게 끝낼 수 있는지, 빌드의 완료나 문제에 따른 알림 처리를 통해 작업에 빠르게 복귀할 수 있는지에 대한 문제는 프로젝트가 커질 수록 더 중요해집니다. 과거의 (물론 현재도) Makefile이 그랬듯이 큰 프로젝트를 관리하는 것은 프로페셔널의 또 다른 모습일 것입니다."


TL;DR;


프로젝트가 커질 수록 깔끔하게 정리되고 빠르고 선택적인 처리, 무언가가 잘못되었을 때 알림을 발생하는 빌드 시스템은 언제나 개발자에게 유용합니다. 이 튜토리얼은 최근 프론트엔드 개발에서 널리 쓰이고 있는 Grunt의 빌드 프로세스 자체를 다음 관점에서 살펴봅니다.

  1. 어떻게 Gruntfile을 산뜻하고 깔끔하게 유지할 수 있는가,
  2. 어떻게 빌드 시간을 극적으로 개선할 수 있는가,
  3. 빌드 시 발생한 이벤트들을 어떻게 전달받을 수 있는가.


> Gruntfile의 체계적인 정리


Gruntfile 체계화하는 것은 지속적인 빌드 설정의 관리와 유지 보수 측면에서 매우 중요합니다.  Gruntfile 내에 수많은 Grunt 플러그인이나 수동 태스크들을 깔끔하게 정리할 수 있는 플러그인들은 다음과 같습니다.

  • Grunt 플러그인의 자동로딩
    • load-grunt-tasks는 package.json 파일을 분석할 것이며 이 태스크가 어떠한 Grunt 플러그인들에 대한 의존성들을 가지는지에 따라 이들 모두를 자동으로 로딩합니다.
  • Grunt 설정의 파일 단위 분리
    • load-grunt-config은 Gruntfile 설정을 작업 단위로 분리하며 load-grunt-tasks 및 그 기능들을 캡슐화해줍니다.


> 빌드 시간의 최소화


웹 앱의 실행 성능은 사업적으로 중요한 의미를 가지지만 빌드 성능은 개발의 반복에 대한 생산성을 담보합니다. 빌드 성능을 개선하기 위한 방법은 다음과 같습니다.

  • 변경 파일들만의 빌드
    • grunt-newer는 실제 파일 변경 정보를 저장하는 로컬 캐시를 통해  변경된 파일들에 대해서만 태스크를 실행합니다.
  • 다중 태스크의 동시 실행
    • grunt-concurrent는 CPU 단위의 스레드를 이용하여 동시에 여러개의 태스크를 실행합니다.
    • 서로에 대해 독립적이며 큰 실행 시간을 필요로 하는 다량의 태스크들을 가지고 있을 때 유용합니다.
  • 빌드 시간의 측정
    • 작업 단위별로 실행 요구 시간을 측정하기 위해 time-grunt를 사용할 수 있습니다.
    • 이는 다른 최적화와 마찬가지로 각 작업에 대한 최적화 지점을 찾을 수 있도록 합니다.


> 자동화된 시스템 알림


만약 다음 빌드가 가능하다던지 빌드 중의 오류를 개발자에게 알려주는 것은 자동화된 프로세스만큼이나 개발자에게 유용할 수 있습니다. 이런 기능이 필요하다면 grunt-notify는 Grunt 에러와 경고 전부에 대해 자동화된 알림을 제공하는 방법으로 사용할 수 있습니다.


보다 자세한 내용은 튜토리얼을 참고하시기 바랍니다.


번역 링크

참고 링크