이 포스트에 있는 내용이 언제나 확실한 정답은 아닙니다. 진실이라고 생각해 왔던 전제가 시간의 지남에 따라 들어나지 않았던 다른 이면 때문에 좋은 방향으로 이끌어 낼 수 있는 역할로 변환 되는게 역사적으로도 많은 증명 있었습니다. 그렇지만 저는 현재 상황에서 최선의 답을 찾고자 노력하였으며 이 글을 읽는 다른 분들에게 다음 길을 갈 수 있도록 도와주는 디딤돌이 되고자 노력하고자 포스팅을 통해 공유하고자 하는 것입니다. 그리고 프로그래머라는 타이틀을 달고 살아야 한다면 "왜"라는 의문을 항상 가지고 다니면서 자신의 위치에 안주하지 않고 항상 노력하는 모습으로 살아 가고자 합니다. 언제든 지적이나 오류가 있으면 피드백 부탁 드리겠습니다.
ing™
Polling에 대해서 알아보기 전에 우선은 Ajax와 인터랙티브 웹 페이지에 대해 간략히 알아 보자. Ajax 통신은 브라우저에서 제공해주는 특별한 객체를 통해(IE - new ActiveXObject("Microsoft.XMLHTTP"), Other - new XMLHttpRequest()) 사용자의 행위에 따라 페이지의 새로 고침 없이 Background에서 서버에서 원하는 데이터를 가져와 페이지의 일부분만을 수정할 수 있는 메커니즘을 말한다. 이런 개발 방식으로 개발된 웹 페이지를 접한 사용자들은 기존의 페이지에서는 느낄 수 없었던 사용자 경험을 얻을 수 있었다. 이 후 수많은 사이트에서 이 개발 방식으로 웹 페이지를 제공하게 되었다. 이런 개발 방식이 조금 더 응용되어 Polling 기법으로 사용자의 행위 없이도 서버에서 변경된 정보를 실시간 - 사용자의 입장에서는 실시간이나 개발자 입장에서는 실시간 지향적 이라 하겠다 - 적으로 업데이트를 할 수 있게 되었다. 간단하게 예를 들면 브라우저에서 서버에게 주기적으로 "데이터가 있어?"라고 물어 보고 서버에서 데이터의 여부에 따라 다르게 대답 하는 것이라 하겠다. 브라우저에서는 받은 데이터로 웹 페이지의 일부분만을 업데이트하여 사용자에게 보여주므로 빠른 응답을 사용자에게 경험하게 할 수 있다. 대표적인 애플리케이션은 웹 채팅이다. 상대방에서 보낸 메시지 여부를 주기적인 Polling으로 알아내어 사용자에게 보여주는 것이다.
Polling의 사전적인 의미를 알아보자. N사이트의 국어사전의 뜻을 보면 다음 표와 같이 풀이하고 있다.
이 뜻풀이처럼 데이터가 필요한 곳에서 제공자에게 송신을 요구하는 패턴을 Polling 방식이라고 할 수 있겠다. 즉 원하는 곳에서 당겨가는 방식이다. 그렇다면 웹 페이지와 서버 간에는 어떻게 Poll이 이루어지고 있는지를 아래 '그림1'을 통해서 전체적인 흐름을 알아 가 보자.
[그림1] Polling 방식
웹 페이지에서 Polling을 구현하는 방식은 setTimeout() 함수를 이용해 주기적인 시간 간격으로 서버에 요청하여 원하는 정보를 얻어오도록 하고 있다.
'그림1'에서와 같이 첫번째 요청처럼 브라우저에서 Ajax로 'Request1'을 요청하면 서버에서는 유효한 데이터가 있는지 조회하고 없으면 개발자가 정의한 형식(여기서는 Empty라고 정의)으로 리턴받고 브라우저 커넥션은 끊어진다.
setTimeOut()함수로 'Request2'요청이 발생할 당시 서버에서 이벤트가 발생하여 유효한 데이타가 있으면 Empty와 대신 개발자가 정의한 형식(여기서는 Message라고 정의)으로 리턴받고 브라우저 커넥션은 끊어진다.
1단계를 다시 시작하여 서버에서 반영된 유효한 값을 브라우저에 업데이트 한다.
위와 같은 방식으로 서버의 변경된 데이터를 브라우저에 지속적으로 반영하여 실시간 반응을 지향하는 웹 페이지를 만들었다.
이제 예제를 통해서 실제적인 코드로 살펴 볼 것이다. ( 실행해 볼 수 있는 소스코드를 마지막 포스트에서 첨부할 것 이니 다운받아 확인할 수 있습니다. )
<!-- Polling 하여 받은 데이터를 반영할 수 있는 DOM --><olid="messages"></ol>
@section scripts{<scripttype="text/javascript">$(function(){// Begin the Polling loopgetNextMessage();});functiongetNextMessage(){// Http post method request
//@Url.Action("GetNextMessage") -> /현재 페이지/GetNextMessage로 치환된다$.post("@Url.Action("GetNextMessage")",function(message){$("<li>").text(message).appendTo("#messages");});// Http get method request//$.get("@Url.Action("GetNextMessage")", function (message) {// $("<li>").text(message).appendTo("#messagees");//});setTimeout(getNextMessage,1000);}</script>}
[코드1] Polling - Browser의 HTML과 javascript 코드
( ASP.NET MVC4의 Razor 문법으로 작성된 코드다. )
위 코드는 페이지가 로딩이 되면 getNextMessage() 함수를 호출하여 서버에 데이터를 요청하고 <ol> 노드에 <li> 노드를 추가하는 코드다. ( 서버 요청을 HttpPost 또는 HttpGet으로 할 수 있다 ) 그리고 setTimeout를 통해 1초후에 다시 getNextMessage()를 호출하도록 되어 있다. 별도의 문제나 행위가 발생하지 않는 한 무한 호출이 되는 단순한 구조로 구성 되어 있다. 이제 아래 코드를 통해 서버쪽의 코드를 알아 보자.
///<summary>/// 요청이 오면 즉시 응답///</summary>///<returns></returns>publicstringGetNextMessage()
{
intwaitingCount=0;
varnow= DateTime.Now;
return"Response at "+now.ToString() +"."+now.Millisecond+" 서버 대기 시간 : "+waitingCount+"ms";
}
[코드2] Polling - Server side 코드
( 서버 사이트 코드는 ASP.NET MVC4 기반에서 작성이 되었다. )
위 코드는 따로 설명을 할 필요도 없을 정도로 간단하여 짧게 설명을 하도록 하겠다. GetNextMessage()함수는 호출이 되면 현재 시간을 알아내 string으로 반환하도록 되었다. 이제 위 결과 화면을 아래 그림을 통해 확인해 보자.
[그림2] Realtime Apps - Polling 실행 결과 화면
( 위 화면은 Visual studio에서 ASP.NET MVC4 템플릿에서 기본 제공되었다.)
'그림2'의 결과 화면을 보면 1초마다 호출된 결과를 화면에 뿌려주는 것을 확인할 수 있다. 이제 코드와 결과 화면까지 확인을 하였다. 이제 Polling이 어떤 방식으로 구성되고 개발되는지 대략적으로 알 수 있을 것이라고 기대한다. 위 예제는 MS 진영에서 개발 및 테스트를 할 수 있지만 Java나 PHP, 기타 Ruby와 같은 곳에서도 비슷한 방식으로 구현이 될 것이므로 이해 하는 데에 크게 무리가 없을 것이라 생각한다.
Tip!
Request가 지속적으로 일어 날 때마다 서버에서는 유효한 사용자의 요청인지를 알아내기 위해 내부적으로 HTTP Handshanking이 지속적으로 일어나기 때문에 오버헤드가 발생한다. 그래서 예측할 수 없는 웹 서비스를 제공하는 서버에서는 성능에 대한 고려를 충분히 해야 한다.
소스 코드 자체에 주석과 직관적인 코딩으로 충분히 파악이 가능할 것으로 예상하므로 별도의 설명을 생략하도록 하겠습니다. 포스트의 내용이 장황한 설명 보다는 주석과 소스코드 자체 만으로도 이해할 수 있도록 하기 위해 노력하였습니다. 실 개발에서도 적용할 수 있도록 간단하면서도 현실적인 예제 프로그램을 통해 각 소스를 만들고 이해 시키고자 하였으며 실무에 필요한 개발요구 사항들을 해결 하는데 도움이 되고자 노력하였습니다. 그리고 소스와 같이 있는 주석을 이용해 nDoc이나 별도의 자동 Document 제작 유틸로 API 문서를 만드는 데에도 도움이 되었으면 한다. ※ DOC에 대한 프로그램 정보 Util link
Real time Apps #1 Polling, LongPolling, Server Sent Events, Websocket, SignalR
실시간 인터랙티브 웹 페이지(또는 앱, 이하 웹 페이지로 통일)에 대해서 익히 들어 봤을 것이다. 사용자의 행동(클릭, 스크롤,...)으로 웹 브라우저에서 서버의 변경된 데이터를 사용자에게 보여 줄 수 있는 웹 페이지 말이다. 사용자의 발전되는 경험으로 인해 오래전부터 인터랙티브형 웹 페이지에 대해 요구되고 있었으며, Ajax 방법론이 대두 되면서 사용자가 만족할 만한 인터랙티브 웹 페이지를 만들 수 있었다. 그렇지만 앞으로의 개발 방향이 기존의 레거시 시스템을 웹을 지원하는 방향으로 흘러가고 있으며 Active-X, Flash, Silverlight를 제외 하고 표준 HTML 과 CSS, Javascript 만으로 C/S 프로그램이 하던 일을 대체해야 한다는 시대적 흐름이 형성 되었다. 그리고 시대적으로 새로운 디바이스(이기종 스마트폰, 이기종 타블렛, Other...)가 출시되었으며 새로운 규격의 브라우저에서도 호환되게 개발해야 한다. 개발자는 이러한 여러 가지 제약 사항을 이겨내고 만족 스러운 인터랙티브형 웹페이지를 구현하기란 쉽지 않다.
그렇지만 개발자들은 고객의 요구 사항을 최대한 만족 시키기 위해 부단히 노력하여 여러 가지 시도로 인터랙티브형 웹 페이지가 되도록 노력하였다. 그래서 Polling, LongPolling등과 같은 방법으로 인터랙티브형 웹 페이지가 되도록 개발하게 되었다. 하지만 처음 설계될 당시의 HTTP 프로토콜과 HTML의 한계성을 가지고 있기 때문에 개발자는 뒤에서 컨트롤하고 사용자에게는 감추는 역할을 더 많이 신경 쓰게 된 것이다. 세계의 여러 개발자들이 이런 문제점을 개선하고자 HTML5와 ECMAScript 6(ECMAScript는 표준화된 스크립트 프로그래밍 언어를 말한다. - 위키피디아 click) 표준이 정립이 되고 있으며 Windows, Linux 같은 또 다른 하나의 개발 플랫폼으로 HTML이 진화를 하고 있다.
HTML5에 대해서 좀더 이야기를 하고 싶으나 주제에 벗어나므로 간단히 정리하고자 한다. HTML5를 짧게 수식 같이 정리하면 아래 '표1'과 같을 것이다.
HTML5 = Javascript + CSS + Templates
[표1] HTML5 정의 표
(이것은 개인적인 정의일 뿐 W3C 공식적인 정리는 아님을 알려 드린다.)
Javascript와 CSS에 대해서는 대부분 알 고 있을 것이라 생각하고 Template에 대해서만 더 설명을 더 하겠다.
Javascript
사용자의 행위에 대해서 처리
CSS
HTML의 레이아웃 및 디자인
Template
HTML Tag의 유동적인 데이터를 템플릿 엔진을 통해 DOM(Document Object Model) 관리가 되도록 한다. Template engine은 JsRender(구 jquery-template), HandleBars와 같이 여러 라이브러리를 통해 얻을 수 있으며 HTML의 대부분 작업을 담당한다.
간단하게나마 HTML5에 대해서 마무리를 하고 이제 본론으로 돌아와 인터랙티브 웹 페이지를 가능 토록하는 방법 중에 서버와의 통신으로 데이터를 가져오는 기법이란 주제로 좁혀 다루고자 한다. 아래 목차대로 하나씩 짚어 나가면서 진행해 보도록 하겠다.
본격적으로 살펴보기에 앞서서 아래 '표1'과 같이 데이터 통신에 관한 기술 정리를 간단하게나마 해 보았으니 참조만 하자.
기술 규격
기술 명칭
COMET
Polling
LongPolling
Hidden iframe
XMLHttpRequest
XMLHttpRequest long polling
Script tag long polling
HTML 5
SSE(Server Sent Events - Streamming) - Not Socket
WebSocket - HTML5
SignalR- hybrid
Socket.IO - hybrid
※ hybrid : 하위 브라우저 호환을 지원하는 기능으로 WebSocket를 지원하지 않는 브라우저에서는 다른 하위 통신 방식으로 데이터 요청을 지원해준다.