Web Skill 트랙

명세서 요구사항 분석 및 설계


1. Front-end

Vue3를기반으로 하는 반응형 SPA(Single Page Application)

1-1. Vue.js 3.0

1-1-1. Vue

Vue.js는 기존 HTML 마크업 기반의 템플릿을 그대로 활용하며 CSS를 작성하는 스타일도 기존 문법을 그대로 따른다. 이때문에 프레임워크를 처음 접하는 사용자들이 진입하기에 부담스럽지않다는 장점이 있다. 또한 확장성 부분에서도 좋은데, jQuery처럼 스크림트 태그로 CDN(Content Delivery Network)를 추가할 수 있고 프로그램에 따라 점진적으로 라이브러리를 채택할 수 있다. Vue.js는 라우팅/상태 관리/빌드 도구 등 공식적으로 지원하는 라이브러리와 패키지를 통해 배포한다. 이러한 확장성은 웹 개발을 더욱 단순하고 쉽게 만들어준다.


1-1-2. Vue.js 3.0 성능 향상

가상 DOM 최적화

기존 Vue 렌더링의 가상 DOM 설계는 HTML 기반 템플릿을 제공하고 이를 가상 DOM Tree로 반환한 후 실제 DOM의 어떤 영역이 업데이트되어야 하는지 재귀적으로 탐색하는 방식이었다. 그렇기에, 매 변경을 파악하기 위해 모든 트리를 확인해야하는 비효율성이 존재했다.

Vue.js 3.0에서는 템플릿 구문에서 정적 요소와 동적 요소를 구분해서 트리를 순환할 때 동적 요소만 순환해서 탐색의 최적화를 반영했다. 또한 렌더링 관련 객체(템플릿 내 정적 요소, 서브 트리, 데이터 객체)등을 컴파일러가 탐지해서 Renderer 함수 밖으로 호이스팅시켜 객체의 복수 생성을 방지한다. 그리고 컴파일러가 템플릿 내 동적 바인딩 요소에 플래그를 생성하여 렌더링 속도를 향상시켰다.


트리쉐이킹 강화

Tree shaking이란 나무를 흔들어 잎을 떨어뜨리듯 모듈을 번들링 하는 과정에서 사용하지 않는 코드를 제거하여 사이즈를 줄이는 최적화 방안을 의미한다.

Vue3는 컴파일러가 실제 사용하는 코드만 import하며, v-model과 같은 양방향 바인딩에서 트리 쉐이킹을 적용해서 번들 크기를 절반 이상으로 줄인다..


1-1-3. Vue.js 3.0 컴포지션 API의 등장

여러 개의 기능이 나누어져 코드 안에 뒤섞이게 되면 컴포넌트의 크기가 커질수록 복잡성이 증가합니다. 복잡한 코드는 가독성이 좋지 않고 논리적으로도 읽기가 힘들어진다. Composition API의 등장으로 코드의 가독성 향상, 재사용성의 개선, Typescript 타입 추론 등의 지원이 가능해졌다.


setup()메서드

기존 컴포넌트 옵션들을 setup() 메서드 내에 선언 및 반환한다. 데이터에 반응형을 부여하는 ref()및 reactive(), 기존의 computed(), watch() 모두 API 메서드들로 대체됐다.


props

this 바인딩을 하던 방식에서, setup()의 첫번째 인자로 받아 내부에서 활용할 수 있다.


emit

this 바인딩을 하던 방식에서, setup()의 두번째 인자인 context에 포함되어있다.


Lifecycle Hooks

beforeCreate, created가 setup()으로 대체된다. 또 hooks 앞에 on들이 붙었으며, destroy는 unmount로 변경되었다.


1-1-4. Vue.js 3.0 기타 변화

Fragment

Vue.js 2에서는 template 내에 단일 태그 매핑을 필수적으로 해야했다. 하지만 Vue.js 3.0에서는 다중 루트 노드를 작성할 수 있게 해준다.


React에서 지원하던 기능

Teleport와 Suspense같이 React와 유사한 부가 기능 컴포너트들이 생겼다.


2. Back-end

Java&SpringBoot를 기본으로 WebSocket, WebRTC 프로토콜을 활용

필요 기능을 구현 하고 REST API 적용

WebRTC 프로토콜을 효과적으로 사용하기 위해, Media Server를 설치하여 활용


2-1. WebRTC(Real-Time Communication)

플러그인 설치 없이 실시간으로 통신할 수 있도록 설계된 API

서로의 장비에서 P2P방식으로 직접 데이터를 전송한다. 별도의 서버를 통해 전송할 필요가 없다.

WebRTC는 클아이언트 웹브라우저에 대한 지연 시간을 줄이는 것이 애플리케이션에 가장 중요할 때 가장 효과적이다. 사용 목적으로는 브라우저 또는 휴대기기에 대한 짧은 지연 시간의 오디오 및 동영상 제공, 바이너리 데이터 또는 키보드, 마우스, 게임 패드 입력과 같은 이벤트의 지연 시간이 짧은 스트리밍, 브라우저 또는 휴대기기에 대한 게임 스트리밍이 있다. 또한 사전 녹화된 미디어나 렌더링된 미디어 대규모 배포, 최신 브라우저에서 지원되지 않는 동영상 형식 스트리밍의 목적으로는 사용하지 않는 것이 더 좋다.

WebRTC 기반의 화상통와흘 하기 위해서는 반드시 서로의 정보를 전달받아야하는데, 이때 시그널링 서버를 사용하며 시그널링 서버는 각각의 클라이언트와 양방향 통신을 해야한다. 이 공통 프로젝트에서는 WebSocket을 사용한다.


2-1-1. 시그널링 서버

WebRTC는 Peer간 직접 데이터를 주고 받는다. P2P 통신으로, 실시간으로 데이터를 전송할 수 있기 때문에, 지연없는 빠른 통신이 가능하다. 하지만 상대방 주소를 모른다면 절대로 서로 통신할 수 없다. 상대방의 정보를 전달받아야하는데, 이런 이유로 시그널링 서버를 별도로 구축해야한다.

시그널링 서버는 상대방의 접속 정보 또는 영상 코덱 정보 등을 실시간으로 전달해야하며, 접속이 끊겼을 때도 상대방이 접속이 끊겼다는 알림을 전달해줘야한다. 즉, 시그널링하는 과정은 클아이언트와 서버 사이에 양방향 통신을 실시간으로 해야한다. 그래서 일반적으로 WebSocket으로 구축하는 경우가 많다.


2-1-2. WebRTC 사용 - 클라이언트

통신에 사용되는 미디어 유형 및 코덱에 동의하는 피어 간의 핸드 셰이크가 필수적이다. 메타 데이터를 교환하면서 WebRTC는 SDP (Session Description Protocol)를 사용하여 클라이언트 간의 메타 데이터에 동의한다.


시그널링 서버에 연결하기 위해 WebSocket 연결을 생성 : var conn = new WebSocket('ws://root/설정한 url');

RTCDataChannel 설정 : RTCPeerConnection 클래스에 대한 객체를 만들어 dataChannel을 만들고 설정할 수 있다.

ICE(Interactive Connection Establish) 연결 설정 : 제안을 다른 peer에게 보낸다. ICE 후보자 처리를 해야한다. WebRTC는 ICE 프로토콜을 사용하여 피어를 검색하고 연결을 설정한다. 다른 피어가 보낸 ICE 후보를 처리하고 이 후보를 수신한 원격 피어는 후보를 풀에 추가해야한다. 다른 피어가 오퍼를 수신하면 이를 Remote Description으로 설정해야한다. 응답을 생성하여 시작 피어로 전송하고 시작하는 피어는 응답을 받고 Remote Description으로 설정한다.

WebRTC는 브라우저에서 미디어 스트림을 가져오기 위한 API를 제공하여 쉽게 전송할 수 있다.


2-2. WebSocket

단방향 통신의 경우 SSE와 같은 기술로도 구현할 수 있다. 하지만 화상 회의 기능은 양방향 통신을 필요로 한다. WebSocket은 TCP연결을 통해서, 양방향 통신 채널을 제공하는 기술이다.


2-2-1. WebSocket 사용

spring-boot-starter-websocket 의존성 추가

WebSocketConfig 클래스를 생성하여 Configuration, EnableWebsocket 어노테이션 추가

registerWebSocketHandlers를 override해서 url 식별

SocketHandler 클래스를 만들어서 TextWebSocketHandler를 확장하여 handleTextMessage 및  afterConnectionEstablished 메서드를 재정의 함으로써 클라이언트로부터 받을 WebSocket 메시지 처리


2-3. WebRTC vs WebSocket

WebRTC는 비디오, 오디오 등의 데이터를 클라이언트 간에 직접 스트리밍 할 수 있어서, 네트워크 성능 비용이 크게 절감된다. 반면에, WebSocket은 클라이언트와 서버 사이의 양방향 통신을 위해 설계되었고 비디오 등의 데이터를 스트리밍 할 수 있지만, WebRTC만큼 효율적이지 않다. 또한, WebSocket은 TCP 프로토콜을 사용하지만, WebRTC는 UDP를 사용한다.


2-4. Media Server

WebRTC 미디어 서버는 WebRTC 기반의 미디어 스트림을 중개 및 분배하는 역할을 하는 서버이다. WebRTC 기반의 방송과 화상회의형 서비스는 이 미디어 서버가 꼭 필요하다. 

미디어 서버는 WebRTC를 다자간 연결로 확장하기 위해 필요한 서버이다. P2P 연결의 경우 송신자와 수신자가 서버 없이 각자의 비디오 및 오디오 등 미디어 스트림을 상대방과 직접 주고 받는 단순한 구조를 가지고 있다. 하지만 3명 이상의 참여자들이 실시간으로 데이터를 주고받고자 한다면 조금 더 고민해봐야한다.

P2P 여결과 마찬가지로 각 피어가 모두 자신의 미디어 스트림을 나머지 피어들에게 직접 전달하거나 여러 피어들이 자신의 미디어 스트림을 중앙의 한 곳으로 보내고 이를 일괄적으로 처리하여 피어들에게 전달하는 방식이 있을 것이다. 전자는 Mesh Networking이고 후자의 방법은 SFU와 MCU라고 부른다.


2-4-1. Mesh Networking

비용이 적게 들고 구현이 간단하짐나 참여자가 많을 수록 스트림의 수가 급격히 늘어나기 때문에 1대1 또는 소규모 미디어 교환에 적합하다.


2-4-2. SFU(Selective Forwarding Unit)

중간 서버에서 별도의 미디어 가공 과정을 거치지 않고 그대로 전달하며 각 피어간 연결 할당/암호화 및 복호화 처리 비용 정도를 감수하고 있다. 서버에 부하가 적게 걸리고 지연시간이 낮아 영상 방송과 같은 1:N 스트리밍 서비스, 또는 N:N 소통에 사용되고있다.


2-4-3. MCU(Multi-point Control Unit)

미디어 스트림을 중앙 서버에서 열람해보고 혼합, 또는 가공하여 수신단으로 전달하는 방식이다. 클라이언트와 네트워크의 부담이 줄어드는 반면 중앙 서버의 CPU 사용량이 매우 커져 높은 컴퓨팅 파워가 요구되는 방식이다.


참고 사이트
WebRTC 사용방법(예제)
[WebRTC] 웹브라우저로 화상 채팅을 만들 수 있다고?
[프로젝트] 실시간 화상채팅앱을 개발했어요! (feat. Socket.IO & WebRTC)
[WebRTC 집중분석④] 1000명이서 실시간 커뮤니케이션을 하는 가장 효과적인 방법