PostIT

[Web/Socket] RTCS 실시간 웹 서비스를 위한 도전 - 퍼옴 본문

Linux/Etc

[Web/Socket] RTCS 실시간 웹 서비스를 위한 도전 - 퍼옴

shun10114 2016. 12. 19. 15:00

* RTCS 실시간 웹 서비스를 위한 도전


HTML, CSS, 자바스크립트만으로 실시간으로 대전할 수 있는 게임을 만들 수 있을까요? RTCS는 HTML과 자바스크립트, CSS, Comet 기술을 활용하여 실시간 웹 서비스를 구현한 기술입니다. 이 글에서는 RTCS의 구성과 구현 방법을 설명합니다.

  실시간 웹 서비스에 도전하다

때는 바야흐로 연말연시, 남들은 놀기 바쁜 이때 뭔가 새로운 시도를 해 보려는 이들이 있었으니...…

"웹으로 신맞고를 만들어 보면 어떨까?"

그 후 한 달여가 지난 뒤 결과물을 보았을 때 놀라움을 금할 수 없었다. 크게 두 가지가 눈에 들어왔는데, 첫째는 HTML, CSS, 자바스크립트만으로 화려한 UI를 구현할 수 있다는 점이었고(사운드만 어쩔 수 없이 플래시 사용), 둘째는 두 사람이 실시간으로 대전할 수 있다는 점이었다. 물론 두 가지 모두 기반 기술이 전혀 새로운 것이 아니라 수년 전부터 사용해 온 기술이지만 짧은 시간에 높은 완성도를 가진 결과물을 개발할 수 있었던 것은 대단한 일이다.

이후 여러 평가에서 좋은 반응을 얻었다. 이것을 실제 서비스에 적용할 수 있도록 재사용 가능한 솔루션으로 발전시키려는 노력을 기울였다. 그리고 다음과 같은 주요 목표를 결정하고 새로운 도전을 시작했다.

  • 접근성: 브라우저만 있으면 어디에서나 활용할 수 있다.
  • 실시간 인터랙션: 사용자와 실시간으로 인터랙션할 수 있다.
  • 대용량: 많은 사용자가 동시에 이용한다.

사내에 다양한 관련 기술이 있어 UI를 비롯한 대부분의 기능은 기존에 개발한 것을 재사용하고, 실시간 커뮤니케이션 기능 개발에 집중하기로 했다. 이름은 RTCS(Real-Time Communication System)라고 지었다. 그 후 두 달여를 진행하여 각 목표에 대해 아래와 같은 내용을 결정했다.

  • 접근성: 주요 5대 브라우저인 인터넷 익스플로러, 파이어폭스, 크롬, 사파리, 오페라를 지원하고 순수하게 HTML, CSS, 자바스크립트만으로 기능을 구현하여 별도의 플러그인 없이 동작하게 만든다.
  • 실시간 인터랙션: Comet 기술을 활용하여 Long Polling, 스트리밍 방식으로 양방향 실시간 통신을 구현한다. 서버 측의 주요 구현부는 톰캣 6.0의 Advanced IO를 기반으로 구현한다.
  • 대용량: 클라이언트와 서버 간 인터랙션 작업과 로직 작업을 분리하여 처리하고 세션 저장소를 분리하여 RTCS 서버의 수평적 확장을 쉽게 한다.

  RTCS 구성 요소와 기능

RTCS는 자바스크립트 기반의 클라이언트 모듈과 톰캣 6.0 Advanced IO 기반의 서버 모듈로 구성된다. 클라이언트와 서버 간의 메시지는 HTTP 기반의 URL 요청과 JSON 형태의 응답으로 처리된다.

다음 그림은 RTCS의 구성 요소를 나타낸다. AJAX와 Comet을 처리하는 'Ajax Client ? On-demand Servlet', 'Comet Client ? Comet Processor/Message Sender'와 양방향 메시지 처리를 보완하는 요소로 구성되어 있다고 볼 수 있다. 그리고 클라이언트와 서버의 로직에서 사용할 수 있는 API를 제공하고 있다.

RTCS1

그림 1 RTCS 구성 요소

기능별 구성 요소를 구분하면 다음 표와 같다.

표 1 RTCS 기능별 구성 요소

기능 구분구성 요소
AJAX 메시지 처리Ajax Client, On-demand Servlet
Comet 메시지 처리Comet Client, Comet Processor, Message Sender
클라이언트 상태 확인(Alive Check)Ping Pong, Idle Checker
RTCS 메시지 처리 및 메시지 유효성 확인Protocol, Checksum
메시지 전송 예외 처리Failover(Browser/Web Server)
클라이언트 메시지 처리 순서 보장Message Queue, Ajax Client
스트리밍 연결의 유효성 확인Heartbeat
클라이언트/서버 로직 구현API 

  서버 Push 방식: Long Polling vs. 스트리밍

RTCS는 Comet의 대표적인 두 가지 방식인 Long Polling과 스트리밍을 지원한다. Long Polling의 경우 기존의 주기적인 Polling 방식(주기적으로 요청하여 결과를 확인하는 방식) 대신 요청에 대한 응답을 서버 이벤트 발생 시점에 받는 방식이고, 스트리밍의 경우는 요청에 대한 응답을 완료하지 않은 상태에서 데이터를 계속 내려받는 방식이다.

주기적인 Polling 방식

주기적인 Polling 방식은 클라이언트, 서버 모두 구현이 단순하다. 요청에 대한 서버 부담이 크지 않거나 실시간 메시지 전달이 크게 중요하지 않은 서비스에 적합하다. 실시간 메시지 전달의 중요성에 따라 요청 주기를 조절할 수 있지만 요청 주기가 짧으면 자칫 서버에 무리를 줄 수 있기 때문에 주의해야 한다. 또한, 실시간 메시지 전달을 고려하여 요청 주기를 짧게 설정하더라도 서버의 상태가 자주 변경되지 않는다면 불필요한 요청/응답 트래픽이 많이 발생할 것이다.

RTCS2

그림 2 주기적인 Polling 동작 구조

Long Polling 방식

Long Polling 방식은 실시간 메시지 전달이 중요하지만 서버의 상태 변경이 빈번히 발생하지는 않는 서비스에 적합하다. 주기적인 Polling 방식에 비해 불필요한 요청/응답 트랜잭션을 덜 유발한다. '덜 유발한다'고 한 이유는 Long Polling 방식도 보통 서버 응답을 무한정 기다리는 게 아니라 특정 시간이 지나면 해당 요청/응답 트랜잭션을 완료하고 새로이 요청하는 방식으로 구현하기 때문이다. RTCS는 클라이언트의 상태 확인(Alive Check)을 위해 ping-pong 방식을 사용하고 있으며 주기를 설정할 수 있다.

RTCS3

그림 3 Long Polling 동작 구조

스트리밍 방식

스트리밍 방식은 한 번 요청 후 응답을 완료하지 않고 해당 응답 스트림으로 필요할 때마다 데이터를 전송하는 방식이다. 응답마다 다시 요청해야 하는 Long Polling에 비해 효율적이며, 서버의 상태 변경이 매우 잦은 경우 유리하다. 하지만 연결을 길게 맺고 있는 경우 연결의 유효성 관리 등의 부담이 발생한다. 스트리밍 방식도 보통 특정 시간을 주기로 연결을 재설정하도록 구현한다. RTCS는 여기에 "최소 전송 보장 길이"를 확인하는 기능이 더 있는데, Long Polling과 달리 요청/응답의 완결 구조가 아닌 상태에서 짧은 메시지가 바로 전달되지 못하는 경우를 대비하기 위해서다. 자세한 내용은 '다양한 네트워크 상황에 대한 대처'절에서 설명한다.

RTCS4

그림 4 스트리밍 동작 구조

  Long Polling과 스트리밍 방식의 구현

RTCS는 클라이언트를 확인하기 위해 sessionKey를 사용하는데, RTCS 클라이언트와 서버가 연결을 초기화할 때 일종의 핸드셰이킹(handshaking) 과정을 거친다. 이때 Long Polling 방식과 스트리밍 방식의 경우 연결 과정이 서로 다른데, 이유는 각 방식의 차이점 때문이다. 따라서 두 방식에 대한 Comet 서블릿(톰캣 6.0 Advanced IO Comet 프로세서의 구현체)을 별도로 구현하고 있다.

Long Polling 방식은 지원하는 5대 브라우저 모두 XMLHttpRequest(이하 XHR)로 구현 가능하지만, 스트리밍 방식은 브라우저별로 XHR, iframe을 Forever Frame, Server-Event 방식으로 구현하고 있는데, 두 방식에 따라 Comet 서블릿을 따로 구현한 첫 번째 이유이다.

두 방식의 연결 내용은 2010 DeView RTCS 발표자료의 3.5, 3.6절을 참조하기 바란다. 브라우저별 스트리밍 처리는 다음 "브라우저별 구현 방법" 절에서 확인할 수 있다.

  브라우저별 구현 방법

RTCS는 5대 주요 웹 브라우저를 모두 지원하기 위해서 각 브라우저별 특성에 맞춰 Comet을 구현했다. RTCS는 Long Polling 방식과 스트리밍 방식을 지원하는데 각각의 경우 브라우저별로 어떻게 구현했는지 살펴보자.

Long-Polling

Long-Polling 방식은 서버에 요청을 보내고 서버 이벤트가 발생할 때까지 연결을 유지한다. 이 상황에서 이벤트가 발생하면 응답을 받아서 처리하고 그 즉시 또 다른 이벤트를 받기 위해 연결을 맺는 방식이다. 방식 자체가 일반적인 HTTP 처리 형태와 별반 다르지 않기 때문에 브라우저별로 동일한 처리가 가능하다. 이때 서버 측에서 이벤트가 발생할 때까지 연결을 맺는 작업은 비동기 처리가 가능한 XHR을 이용하여 AJAX 방식으로 구현했다. 주요 자바스크립트 코드는 다음과 같다.

function longPoll(url, callback) {  
var xhr = new XMLHttpRequest();  
xhr.onreadystatechange = function() {  
if(xhr.readyState == 4) {  
// 응답이 완료되면 서버로
//재연결 요청보내기
callback(xhr.responseText);  
xhr.open('GET', url, true);  
xhr.send(null);  
}
}
// 서버로 요청 연결하기
xhr.open('POST', url, true);  
xhr.send(null);  
}

스트리밍

스트리밍 방식은 클라이언트에서 요청을 보내면 서버에서 응답을 보내지 않고 계속 연결을 유지한다. 그 연결을 통해 HTTP/1.1의 Chunked 인코딩 방식을 이용하여 이벤트가 발생할 때마다 서버에서 클라이언트로 결과를 전송한다. 연결을 맺고 있는 상태에서 계속 이벤트를 줄 수 있으므로 이벤트가 빈번하고 실시간 메시지 전달 이슈가 큰 서비스에 적합하다.

스트리밍 방식의 경우도 XHR을 이용하는 것이 가장 좋으나, 인터넷 익스플로러와 오페라의 경우 XHR 처리 시 응답이 완료되지 않은 상태로 전송된 데이터에 접근이 허용되지 않는다. 따라서 다른 방법을 이용했다. 브라우저별로 스트리밍 방식을 구현하기 위해 결정한 사항은 다음과 같다.

표 2 브라우저별 스트리밍 방식 구현

적용 브라우저구현 방식설명
파이어폭스, 크롬, 사파리XHR 스트리밍XMLHttpRequest를 이용하여 스트리밍 구현
인터넷 익스플로러Forever Frame IFrame과 Script Flush 방식을 이용하여 스트리밍 구현(htmlfile 액티브X 컨트롤 이용)
오페라Server-Sent Events HTML5의 Server-Sent Events를 이용

XHR 스트리밍 방식

XHR 스트리밍 방식은 모든 웹 브라우저에서 지원하는 사실상의 표준인 XHR을 이용하여 서버와 장시간 연결하는 것이다. XHR을 이용하면 응답 결과의 텍스트뿐 아니라 헤더에도 직접 접근할 수 있고 장애(fail-over)도 비교적 쉽게 처리할 수 있다.

이 방식으로 클라이언트에서 이벤트를 받는 원리는 다음과 같다.

  • XHR의 onreadystatechange 이벤트가 발생하면 readyState 변수를 확인한다.
  • readyState 변수가 3일 때, 요청 연결 후부터 현재까지 서버로부터 받은 결과에 접근한다.
  • 결과 중 마지막 이벤트에 해당하는 텍스트를 가져온다.

readyState 변수가 3인 경우 서버에서 추가적인 응답이 발생한 것이고, 4인 경우 서버의 응답이 완료된 것이다. 일반적인 AJAX 전송에서 XHR을 이용할 때는 readyState가 4인 경우가 중요하지만, XHR 스트리밍 방식에서는 이벤트 발생 시점을 처리하므로 readyState가 3인 경우가 더 중요하다.

XHR 스트리밍 방식에 대한 클라이언트 측의 주요 자바스크립트 코드는 다음과 같다.

function xhrStreaming(url, callback) {  
var xhr = new XMLHttpRequest();  
xhr.open('POST', url, true);  
var lastSize;  
// 최신 텍스트를 가져오기 위한 위치
xhr.onreadystatechange = function() {  
var newTextReceived;  
if(xhr.readyState > 2) {  
// 최신 텍스트 가져오기
newTextReceived =  
xhr.responseText.  
substring(lastSize);  
lastSize =  
xhr.responseText.length;  
callback(newTextReceived);  
}
if(xhr.readyState == 4) {  
// 응답이 완료되면
//새로운 요청을 다시 만든다
xhrStreaming(url, callback);  
}
}
// 서버로 요청 연결하기
xhr.send(null);  
}

인터넷 익스플로러와 오페라에서는 readyState가 3일 때 보안상의 이유로 응답 결과에 접근을 허용하지 않는다. 따라서 다음 절에서 설명하는 다른 방식을 이용해야 한다.

Forever Frame 방식

XHR 스트리밍 방식을 구현할 수 없을 경우 차선책으로 예전부터 웹 기반 채팅을 위해 주로 사용되던 방식인 Forever Frame 방식을 고려할 수 있다. 이 방식은 페이지에 보이지 않는 IFrame을 생성해서 HTTP/1.1의 Chunked 인코딩 방식을 기반으로 Comet 서버와 연결을 맺어둔다. 이를 이용해 서버에서 이벤트가 발생할 때마다 Script Flush 방식으로 클라이언트에 원하는 데이터를 전송하는 방식이다. 다음은 동적으로 IFrame을 생성하여 Comet 서버에 연결을 맺는 자바스크립트 예제 코드이다.

function foreverFrame(url, callback) {  
var iframe = body.  
appendChild(  
document.  
createElement("iframe"));  
iframe.style.display = "none";  
iframe.src =  
url + "?callback=parent.foreverFrame.callback";  
this.callback = callback;  
}

그리고 Comet 서버에서 이벤트가 발생할 때 Script Flush 방식으로 전송되는 메시지는 다음과 같다.

<script>parent.foreverFrame.callback("the first message");</script>  
<script>parent.foreverFrame.callback("the second message");</script>  

하지만 위와 같은 방식을 인터넷 익스플로러와 오페라에서 구현해보니 사용자 경험에 있어 실제 서비스에 적용하기 어려운 몇 가지 문제점이 발견되었다. 첫 번째는 이 방식으로 Comet 서버에 연결하면 웹 브라우저의 상태 표시줄에 연결 중임을 계속 표시하는 것이고, 두 번째는 서버에서 이벤트가 발생해서 클라이언트에 전달될 때마다 클릭하는 소리가 나는 것이다. 다행히 인터넷 익스플로러에서는 htmlfile이라는 액티브X 컨트롤을 이용해서 앞의 문제점을 해결할 수 있는 방법이 공개되어 있었다. 또한 이 방법은 2006년에 구글 Talk 서비스에 처음 적용되어 Comet 커뮤니티에서는 이미 대중화된 방법이었다.

다음 코드는 htmlfile을 이용하여 Forever Frame 방식을 구현한 예제이다. 앞의 자바스크립트 코드와 비교해보면 빨리 이해할 수 있다.

function foreverFrameByHtmlfile(url, callback) {

// 명시적인 가비지 콜렉터 호출을 위해
//'var transferDoc...'라고 하지 않음

transferDoc = new  
ActiveXObject("htmlfile");  
transferDoc.open();  
transferDoc.write("");  
transferDoc.close();  
var ifrDiv =  
transferDoc.createElement("div");  
transferDoc.body.appendChild(ifrDiv);  
ifrDiv.innerHTML ="";  
transferDoc.callback = callback;  
}

function foreverFrameClose() {

// transferDoc 참조를 없애고,
// 명시적으로 가비지 콜렉터를 호출함

transferDoc = null;  
CollectGarbage();  
}



// 페이지가 이동되거나
// 창이 닫힐 때 호출함수 지정

window.onunload = foreverFrameClose;  

Server-Sent Events 방식

htmlfile을 이용하여 Forever Frame 방식의 문제점을 해결한 인터넷 익스플로러와 달리 오페라의 경우는 Forever Frame 방식을 위한 별다른 해결책이 없었다. 그래서 다른 방식을 찾아보았는데, HTML5에 정의된 서버 푸시(Server Push) 기술의 표준인 Server-Sent Events API를 2006년에 출시된 오페라 9버전부터 이미 지원하고 있다는 것을 알게 되었다. 따라서 현재 사용 중인 오페라는 거의 대부분 Server-Sent Events API를 지원한다고 볼 수 있으므로 이 방식을 적용하기로 했다. 다음 코드는 이 방식으로 Comet 서버에 연결하는 자바스크립트 예제이다.

function serverSentEvents  
(url, callback) {
var eventSource =  
document.  
createElement('event-source');  
handler = function(event) {  
callback(event.data);  
};
eventSource.  
addEventListener('rtcs-event',  
handler, false);  
eventSource.addEventSource(url);

// 오페라 9.60 이후부터 아래처럼 url을 지정하면 handler가 2번 호출됨
//eventSource.
setAttribute('src', url);  
document.body.  
appendChild(eventSource);  
}

크로스 도메인 처리

앞에서 설명한 것과 같이 RTCS 클라이언트에서 Comet 구현을 위해 주로 이용한 것이 XHR인데, 이것은 아주 엄격한 SOP(Same Origin Policy)를 적용 받고 있다. 이 정책으로 보안성은 강화되었으나 페이지 서버와 접속 서버의 도메인이 서로 다르면 골치 아픈 문제가 발생한다.

RTCS를 실제 서비스에 적용할 때 트래픽을 분산 관리하기 위하여 웹 서버와 Comet 서버를 분리할 가능성이 매우 크다. 즉 크로스 도메인(Cross Domain) 상태가 되는 것이다. RTCS에서는 이런 경우를 위해 다음과 같이 IFrame을 이용하여 2차 도메인까지만 동일하면 SOP의 제약을 피할 수 있도록 하였다.

RTCS5

그림 5 2차 도메인 허용시 동작 구조

위의 그림에서 페이지가 호출하는 서버와 RTCS 서버의 도메인은 서로 다르다. RTCS 클라이언트에 필요한 최소한의 HTML 페이지 소스와 자바스크립트 코드는 숨겨진 IFrame을 이용하여 RTCS 서버로부터 전송받기 때문에 RTCS 서버와 Comet을 연결할 때 SOP를 위배하지 않는다. 또한 서비스 페이지는 다음과 같이 명시적으로 2차 도메인까지 동일하다는 선언만 하면 양쪽으로의 코드 접근이 가능하므로 크로스 도메인 문제를 해결할 수 있다.

document.domain = "hangame.com";  

보안 처리

RTCS를 개발하려는 목적이 웹 게임을 위한 기반 솔루션이다보니 보안을 중요하게 생각해야 했다. 2가지 측면에서 고려했는데, 클라이언트 상태 변조를 막는 클라이언트 보안과 서버와 클라이언트 간의 전송 데이터 변조를 막는 전송 보안이다.

클라이언트 보안

RTCS 기반의 웹 게임 또는 서비스에서 클라이언트 로직은 대부분 자바스크립트로 통해 구현된다. 따라서 누구나 쉽게 소스 코드를 볼 수 있고 실행 중인 로직을 변경할 수도 있다. 이를 방어하는 여러 가지 기법을 적용하더라도 완벽한 보안은 불가능하다. 또한 보안을 위해 여러 장치를 마련하더라도 스크립트 코드의 한계로 그에 따른 성능 저하가 쉽게 나타나므로 적용이 쉽지 않다. 특히 사용자의 PC 환경과 웹 브라우저 종류에 따라 그 정도가 달라지는 것도 큰 문제이다. 따라서 성능 저하가 비교적 적고 효과가 큰 다음과 같은 방식을 적용하였다.

  • 자바스크립트 코드 압축 및 난독화
  • 주요 로직은 모두 서버에서 처리하고 클라이언트에서는 주로 UI 처리에 집중

전송 보안

서버와 클라이언트 간의 웹 전송을 안전하게 할 수 있는 방법으로 HTTPS를 생각해볼 수 있다. 하지만 HTTPS는 충분히 신뢰할 수 있는 수단을 제공하는 대신 그만큼 비용과 성능에 문제가 있어 실시간 데이터 전송에는 어울리지 않는다. 그래서 암호화 데이터를 직접 처리하려 했으나 이번에도 자바스크립트의 성능이 문제였다. 즉 암호화/복호화 코드의 은닉이 사실상 불가능한 자바스크립트 코드에서 활용 가능한 암호화 방식은 공개키 알고리즘인 RSA 방식 정도인데 테스트 결과 성능상 서비스에 적용하기 힘든 결과가 나왔다.

결국 메시지 자체는 JSON 형태 그대로 보내고, 대신 원본 메시지의 무결성을 검증하는 일종의 Checksum 방식을 적용하였다. 실제로 RTCS는 이 방식의 보안성을 좀 더 높이기 위해 HMAC 알고리즘을 적용하였다.

다양한 네트워크 상황에 대한 대처

스트리밍 방식의 경우 응답 연결을 통해 계속 서버의 메시지가 전달되는데, 이때 너무 작은 메시지가 브라우저별 최소 유효 메시지 길이보다 작거나 프록시 등의 네트워크 환경에 따라 바로 전달되지 않는 경우를 감안하여 "최소 전송 보장 길이"라는 것을 구현했다.

"최소 전송 보장 길이"는 스트리밍 방식의 핸드셰이킹 과정에서 계산하게 되는데, 연결을 통해 sessionKey 정보를 전달하면서 더미(dummy) 메시지를 함께 전달한다. 그럼 클라이언트에서는 최소 이벤트가 발생한 시점에 받은 메시지 길이를 계산하여 "최소 전송 보장 길이"를 정하게 되고 이를 RTCS 서버에 전달한다. 다음 그림은 이 과정을 도식화한 것이다.

RTCS6

그림 6 최소 전송 보장 길이 설정 구조

서버 메시지 전송 실패 시 처리는?

Long Polling, 스트리밍 두 방식 모두 연결을 재설정하는 순간이 있다. 하나의 요청에 대한 응답을 종료하고 새로운 요청을 시작하는 사이에 서버에서 메시지를 전송하려고 할 경우 해당 RTCS 세션의 응답 연결이 유효하지 않기 때문이다. 이 경우 RTCS는 메시지를 세션별 장애 처리 메시지 큐(FailOver Message Queue)에 저장해 두었다가 연결이 다시 유효해지면 전송하게 된다. 이 부분은 RTCS 서버 구현에서 메시지 전송을 보장하는 가장 주요한 부분이다. 아래 그림은 장애 처리 과정을 도식화한 것이다.

RTCS7

그림 7 서버 메시지 전송 실패 시 장애 처리 구조

대용량 처리

앞에서 설명한 구성 요소 중 RTCS 서버는 로직에서 이용할 수 있는 API를 제공하고 있다. 제공하는 프로세서의 인터페이스를 구현하여 RTCS 서버에 로직을 구현할 수도 있다. 하지만 이 경우 로직을 수평적으로 확장하는 것이 어려워진다. 그래서 별도의 로직 서버를 구성하고 RTCS 서버에서는 프로세서의 인터페이스를 구현하여 해당 로직 서버와 연계하는 커넥터(Connector)를 구현하도록 가이드하고 있다. 기본적으로 BLOC 서버 통신을 위한 커넥터가 구현되어 있으며, 반대로 로직 서버에서 RTCS 서버에 연결된 클라이언트에 메시지를 전송하기 위한 RTCS 서버 API 모듈을 제공하고 있다.

그런데 아직 해결되지 않은 문제가 있었으니 바로 로직 서버에서 특정 RTCS 클라이언트에 메시지를 전송하고자 할 때 해당 클라이언트가 어느 RTCS 서버에 연결되어 있는지 알기 힘들다는 것이었다. 그래서 RTCS 세션 정보를 공유할 별도의 세션 서버를 도입하게 되는데, 현재 적용 중인 서비스에는 Arcus를 도입하였다.

RTCS8

그림 8 로직 서버, 세션 서버와의 연동

RTCS 기반 서비스 구성하기

다음은 RTCS 기반으로 서비스를 구성하는 경우에 대한 예시이다. 웹 서버의 경우는 기존과 마찬가지로 HTML 페이지와 정적인 리소스를 처리하고 실시간성 요청 및 서버 메시지는 RTCS 클라이언트와 RTCS 서버가 처리한다. 앞에서 설명한 것 같이 RTCS 서버와 로직 서버를 분리하고 별도 세션 저장소를 두어 RTCS 세션을 관리한다.

RTCS9

그림 9 RTCS 기반 서비스 구성

앞으로 할 일

현재 국내외 웹 서비스 개발의 최대 화두는 단연 HTML5일 것이다. HTML5에는 Comet 기술을 완전히 대체할 수 있는 Native 브라우저 구현 기술이 정의되어 있는데, 그것이 바로 웹 소켓(WebSocket)이다. 웹 소켓은 웹 기반의 안전한 TCP 소켓을 말하며 클라이언트와 서버 간의 양방향 통신(Full Duplex)이 가능하다. 물론 기존 Comet 기술보다 성능도 더 좋을 것이다. 따라서 언제가 될지는 아직 정확히 모르지만 HTML5가 대중화될 때를 대비해서 RTCS도 웹 소켓을 적용할 수 있도록 준비해야 할 것이다. 사실 RTCS 클라이언트의 주요 API는 웹 소켓의 API 형태를 참고하여 구현했다. 그 이유는 향후 웹 소켓이 대중화되었을 때 쉽게 웹 소켓으로 교체 또는 브라우저별로 기존 Comet 방식과 병행 적용할 수 있도록 하기 위함이다.

(이 글은 2010년 11월에 작성한 것이다. 당시의 RTCS에 비해 성능이 크게 향상되고 톰캣뿐만 아니라 Jetty도 지원하는 RTCS 1.0 버전이 2011년 9월에 정식으로 릴리스되었다. 초기 구현에서 병목 현상을 일으키던 부분을 새롭게 설계하고 구현하여 비약적인 성능향상이 있었다. 이 내용은 2011년 11월에 개최된 KGC2011에서도 공유되었다.)

참고하면 좋은 자료 : https://www.xpressengine.com/tip/23056976

Comments