인터랙티브로 말하는 웹과 웹앱 개발에 필요한 MVC 프레임웍의 기초 지식

( jQuery template )


참조 URL
  1. https://github.com/BorisMoore/jquery-tmpl



인터랙티브로 말하는 웹과 웹앱 개발에 필요한

 MVC 프레임웍의 기초 지식

jQuery data binding )


참조 URL
  1. https://github.com/jquery/jquery-datalink
  2. http://blog.naver.com/PostView.nhn?blogId=loudon23&logNo=30096650420&parentCategoryNo=36&viewDate=
  3. http://jsfiddle.net/rniemeyer/4FdcY/
  4. http://blog.outsider.ne.kr/532



2013/09/21 - [HTML5] - 인터랙티브로 말하는 웹과 웹앱 개발 에서 언급이 되었던 DataBinding에 대해서 좀더 알아 보도록 하겠다.



Data Binding을 이용하면 편리하게 객체값에 대해서 DOM과 동기화를 수행할 수 있다. 예로 사용자가 웹 페이지에서 값을 입력하면 입력된 값을 자바스크립트로의 값으로 변환해야 한다. 그리고 반대로 자바스크립트의 값이 변경 되면 웹 페이지에도 반영을 해야 한다. 지 작업을 개발자가 일일이 수행해야 했다. 그렇지만 jQuery의 DataLink를 이용하면 two-way 방향으로 자동으로 동기화가 되게 된다. 개발자는 코드로 보여주는 것이 이해가 빠르므로 아래 코드를 살펴보자.

(여기서 소개하는 jQuery의 DataLink는 약 2년정도 전에 발표가 되었으며 AngularJS나 KnockOutJS의 DataBinding의 개념을 이해 시키기 위해 소개하는 기술임을 알아두기 바란다.)


<script src="~/Scripts/jquery-1.8.2.js"></script>
<script src="~/Scripts/jQuery.DataLink.js"></script>
 
<script>
    // 객체 선언
    var person = { };
 
    $().ready(function () {
        // 데이터와 HTMl을 연결 시킨다.
        $("form").link(person, {
            firstName: "firstName",
            age: "age",
        });
 
        // person의 firstName이 비어 있는지 체크
        logWrite(person.firstName);
 
        // datalink로 firstName에 새로운 값을 넣는다.
        // 내부적으로 링크되어 있는 노드에 값이 변경됨을 알려 준다.
        $(person).setField("firstName", "새로운 값");
        $(person).setField("age", "30");
 
        // 값이 변경 되었는지 체크한다.
        logWrite('person : ' + JSON.stringify(person));
        // 자바스크립트의 객체만 변경 하였으나 HTML 노드의 값이 변경이 제대로 되었는지 체크
        logWrite('input text : ' + $("#firstName").val());
 
        // Form안에 있는 input 테크에서 값이 변경이 되면 실행
        $("form").change(function () {
            // person의 값을 로그에 찍어 준다.
            logWrite('person : ' + JSON.stringify(person));
        });
    });
 
    // 로그로 저장이지만 HTMl 노드에 보여주는 역할을 한다.
    function logWrite(msg) {
        $('#log').append('<li>' + msg + '</li>');
    }
 
    // 버튼 클릭시 객체의 값을 변경
    function personNameChange(str) {
        $(person).setField("firstName", str);
    }
</script>
 
<form name="person">
    <label for="name">Name:</label>
    <input type="text" id="firstName" name="firstName" />
    <input type="text" id="age" name="age" />
    <button onclick="personNameChange('클릭으로 객체 값 변경'); return false;">객체 값 변경</button>
    <br />
    <ul id="log"></ul>
</form>

[코드1] jquery의 datalink를 이용해서 DOM과 연결하는 코드


- $("form").link(person, { }) : Datalink의 확장 메소드로 자바스크립트의 person 객체와 DOM ( HTML Tag )을 연결한다.

- $(person).setField("firstName", "새로운 값") : person 객체에 값을 변경하고 내부적으로 연결된 DOM의 값을 변경하여 준다.

- logWrite('person : ' + JSON.stringify(person)) : person의 값을 JSON 형식으로 만들어서 로그에 저장한다.



이제 양방향으로 연결되었으니 화면으로 확인해 보자.



[그림1] jQuery의 Datalink로 연결된 화면


1. 처음에는 person.firstName의 값이 할당되어 있지 않기 때문에 'undefined' 로그에 출력 되었다.

2. person의 값이 정상적으로 할당이 되었는지 체크한 로그

3. person의 변경된 값으로 input 값이 바로 변경되었는지 체크한 로그

4, 5. 사용자가 input에 값을 변경한 그래도 person의 값이 반영된 로그

6. '객체 값 변경' 버튼을 눌러 person의 값을 변경하였을 때 정상적으로 DOM에 반영된 로그


위와 같이 Data binding을 사용하면 사용자의 값을 추적하는 번거로운 작업을 개발자가 아닌 라이브러리에서 관리가 되므로 좀더 많은 시간을 비지니스 로직에 투자할 수 있다.











인터랙티브로 말하는 웹과 웹앱 개발


참조 URL
  1. http://k2unip.tistory.com/103
  2. http://helloworld.naver.com/helloworld/179084
  3. http://calmglow.egloos.com/4792335
  4. http://googledevkr.blogspot.kr/2013/07/webapp-with-google-drive.html
  5. http://webapp.pe.kr/rb/
  6. http://h5bak.tistory.com/2


N사이트 사전으로 '인터랙티브'의 의미를 알아 보면 ['상호간'의 뜻을 지닌 인터(Inter-)와 '활동적'의 뜻을 지닌 액티브(Active)의 합성어로, 상호활동적인, 곧 쌍방향이라는 의미를 지닌다. 사용자가 마치 컴퓨터와 대화를 하듯이 입력출력을 할 수 있는 프로그램으로...]라고 정의 되어 있다. 실제 개발에서 인터랙티브한 웹( 또는 웹앱)을 지원하기 위해서는 사용자의 반응에 빠르게 응답할 수 있도록 설계되어야 할 것이다. 이번에는 웹과 웹앱 개발에서 사용자의 반응에 빠르게 반응할 수 있도록 해주는 방법에 대해서 개략적으로 알아 보도록 하겠다.

우선 웹과 웹앱에 대한 기본적인 구동에 대한 차이점을 아래 "그림1, 2"로 흐름을 알아 보도록 하자.

[그림1] 일반적인 웹 페이지 네비게이션 흐름


일반적인 웹은 웹 페이지에 필요한 자바스크립트나 CSS 또는 이미지들을 사용자의 네비게이션의 이동마다 전체적으로 다시 다운받아 브라우저에서 초기화를 진행하고 랜더링을 하는 구조다. 위 '그림1' 에서와 같이 왼쪽에서 오른쪽으로 페이지 이동이 일어 나고 그때마다 모든 파일을 서버에서 다운받고 있다. 이런 구조가 지금까지 대 부분의 웹 페이지에서 일어나는 흐름이다. 대표적으로 N 사이트의 모바일 전용 사이트(m.naver.com)에서도 이와 같은 구조로 되어 있다.


[그림2] 웹앱 네비게이션 흐름


웹앱은 기본적으로 UI에 필요한 자바스크립트와 CSS 그리고 이미지들을 최초 초기화때에 모두 가져온다. ( 또는 웹앱으로 배포된 앱은 같이 배포가 되어 있다.) 그리고 UI 이외의 요소인 데이터만 웹 서버를 통해 추가적으로 가져와서 사용자의 반응에 따라 필요한 UI를 페이지 전환 없이 사용자에게 보여준다. 

사용자의 입장에서 어떤 구조가 더 빠르게 반응할 수 있는지는 굳이 증명 하지 않아도 알 수 있을 것이다. 그래서 요즘에는 웹에서도 위와 같은 구조를 지원하기 위해 여러가지 라이브러리들이 개발되고 있다. 이런 라이브러리들을 아래에서 웹앱 개발을 지원하는 프레임웍에 대해서 먼저 검토하고 알아 보도록 하겠다.

웹앱 개발을 지원하는 대표적인 프레임웍은 "Sencha Touch"와 "jQuery Mobile"이 있다. Sencha Touch는 가장 화려한 UI와 편리한 기능들을 제공하는 컴포넌트들이 있어서 어렵지 않게 웹앱을 만들 수 있다. 그렇지만 Sencha Touch를 사용하면 다른 라이브러리와의 연동이 상당히 제한되어 개발자의 창조적인 사고에 영향을 받을 수 있다. 그와 반대로 jQuery Mobile은 유명한 jQuery 진영에서 개발된 프레임웍이며 기존 그대로 jQuery를 사용하여 개발 할 수 있다. 그리고 수많은 오픈소스 진영에서 활발하게 개발되고 있어서 앞으로의 발전이 가장 많이 될 것으로 기대하고 있다. 그리고 jQuery Mobile는 제일 많은 플랫폼을 지원하고 있어서 한번만 개발하여 배포만 거의 모든 환경에서 사용할 수 있을 것이다. 


[그림3] 센차터치 데모 예시

( http://www.sencha.com/products/touch )



[그림4] jQuery Mobile 사이트에서 모바일 화면을 구성하는 화면

( http://jquerymobile.com/ )


jQuery Mobile 사이트에 들어가 보면 '그림3'과 같이 웹에서 직접 UI를 그려보고 테스트를 할 수 있도록 지원하고 있다. 필자가 드래그 앤 드롭으로 Header, Footer, Link, Button... 등등을 넣어서 테스트한 화면을 '그림4'에서 처럼 확인할 수 있다. 그리고 오른쪽 위 상단에 'Download HTML'을 클릭하면 내가 편집한 화면을 그대로 다운로드 받는 것을 지원한다. 다운로드 받은 파일을 압축해제 하면 '그림5'와 같은 파일을 확인할 수 있다.



[그림5] 다운로드 받은 압축 파일을 해제한 폴더 화면



이 파일을 바탕으로 구현하고자 하는 웹앱을 완성하면 될 것이다. 그리고 이런 방법외에도 아래 '그림6'처럼 갤러리를 제공하고 있어서 디자인이나 레이아웃 또는 기법들을 검토할 수 있는 웹 사이트까지 제공하고 있다.



[그림6] jQuery Mobile로 만든 사이트 갤러리


이 갤러리를 이용해서 내가 만들 웹앱에 대한 영감을 얻어 사용자에게 좀더 편리하고 완성된 웹앱을 만드는 밑거름으로 사용하기를 바란다.



이제 일반적인 웹 페이지에 대해서 접근해 보도록 하겠다. 웹 개발이 발전하면서 일반 웹에서도 웹앱과 같은 구조를 지향하기 위한 방법론이 거두되면서 SPA라는 개념이 나오게 되었다. 위키 피디아에서 SPA( http://en.wikipedia.org/wiki/Single-page_application )를 '데스크탑 애플리케이션에 더 가까운 더 유연한 사용자 경험을 제공하는 것을 목표로 하나의 웹 페이지로 만든 웹 응용프로그램 또는 웹 사이트이다'라고 되어 있다. SPA의 형식이야 어떻든 웹앱과 전체적인 구조와 비슷하게 같이 가져 간다는 것이다. 그리고 SPA를 지원하기 위해서 여러가지 프레임웍과 라이브러리가 생겨나게 되었다.


웹앱이나 SPA는 하나의 웹 페이지에서 여러개의 비지니스 로직을 포함하기 위해 방대한 자바스크립트의 관리가 힘들게 되었다. 그래서 자바스크립트를 모듈화 해주는 프레임웍과 비 동기적으로 자바스크립트를 가져와 실행되도록 해주는 비동기 지원 라이브러리의 등장이 있었고 각각의 특징들을 모아 자바스크립트 MVC(Model-View-Controller) Framework이 등장하고 End-to-End 방식으로 지원하는 프레임웍까지 등장하게 되었다. 


 역할

 라이브러리 명 

 모듈화 지원

 - Backbone.js ( http://backbonejs.org/ ) 

 비 동기 로드 지원

 - RequireJS ( http://requirejs.org/ ) 

 MVC(Model-View-Controller) 프레임웍 

 - AngularJS ( http://angularjs.org/ )

 - knockoutJS ( http://knockoutjs.com/ )

 End-to-End 프레임웍

 - Meteor ( http://www.meteor.com/ ) on Node.js

 - Derby ( http://derbyjs.com/ ) on Node.js

[표1] 역할 별 자바스크립트


※ 자바스크립트 MVC는 서버사이드에서 처럼 브라우저단에서도 데이터와, 뷰와 로직 처리를 분리하여 개발 및 확장, 유지보수성을 높이고 최저 품질을 높이기 위한 방법을 지원하자는 취지로 만든 프레임웍이다.

※ End-to-End 프레임웍은 Node.js 진영에서 지원되는 프레임웍으로 서버에서 브라우저까지 모두 자바스크립트로 개발할 수 있도록 되어 있다.

※ AngularJS, KnockOutJS는 Databinding을 지원한다. DataBinding이란 자바스크립트의 객체값으로 HTML의 테그와 양 방향 통신을 하여 일치 시켜 주는 작업을 지원하는 것을 말한다. 그래서 개발자는 HTML 테그를 컨트롤 할 필요 없이 자바스크립트 객체 값만 변경 시키면 UI는 저절로 변경이 일어난다. ( '그림9' 참조 )



[그림7] MVC를 지원하는 AngularJS


[그림8] MVC를 지원하는 KnockOutJS



[그림9] KnockOutJS에서 Databinding의 예시 ( http://learn.knockoutjs.com/#/?tutorial=custombindings )



이런 라이브러리들은 개발자의 사소한 실수를 줄이고 고 품질의 코드를 작성 할 수 있도록 개발자를 고양시켜 주기도 한다. 여기서 언급된 라이브러리들이 생소하다면 지금 부터라도 하나 하나씩 접해 보면서 자기만의 것으로 만들어 보기를 적극적으로 권해 드린다.


마지막으로 필자가 생각하는 라이브러리를 익혀 나가는 순서는 아래와 같다.


- Backbone으로 모듈화 및 기본적인 MVC의 개념을 잡고

- Requirejs로 비 동기적으로 js을 불러와 네트워크 트래픽을 분산 시키는 기법을 익히고

- Backbone + Require 또는 AngularJS + RequireJS(KnockOutJS + RequireJS)의 조합으로 MVC를 좀더 심화 시킨다.

  (AngularJS는 구글에서 KnockOutJS는 MS에서 서포트 해주고 있다.)


이와 같은 순서로 점진적으로 고급기법들을 익혀 나가다 보면 사용자에게 보다 빠르고 에러가 나지 않는 신뢰할 수 있는 웹페이지를 제공할 수 있을 것이고 핵심 로직에만 집중할 수 있기에 보다 높은 품질의 코드를 작성할 수 있게 될 것이다. 그렇게 된다면 프로그래머로서 현재 보다 더 만족스러운 삶을 살 수 있을 것이라고 기대하면서 이 글을 마치겠다.




Visual Studio New Feature - 새로운 기능들


참조 URL
  1. http://blogs.msdn.com/b/somasegar/archive/2013/09/09/announcing-the-visual-studio-2013-release-candidate.aspx
  2. http://www.microsoft.com/visualstudio/kor/2013-preview#story-2013preview
  3. http://www.microsoft.com/visualstudio/eng/2013-preview#story-2013preview
  4. http://msdn.microsoft.com/en-us/library/vstudio/bb386063(v=vs.120).aspx
  5. http://blogs.msdn.com/b/visualstudio/archive/2013/07/15/visual-studio-2013-new-editor-features.aspx



- Peek Definition (Alt + F12)

- Enhanced Scrollbar

- Navigate To (Ctrl+,)

- Auto Brace Complete

- Move Line Up/ Down (Alt Arrow-Up/ Arrow-Down)

- New IDE Features for Visual C++

- New IDE Features for JavaScript

- ...


자세한 사항은 위 링크에서 직접 알아 보기를 바랍니다.









Real time Apps #6 - SignalR over WebSocket


참조 URL
  1. http://signalr.net/
  2. http://techbrij.com/jquery-flot-signalr-asp-net-mvc-chart
  3. http://www.asp.net/signalr/overview/getting-started/introduction-to-signalr
  4. http://brad.tistory.com/category/SignalR
  5. http://www.codeguru.com/csharp/.net/sending-notifications-using-asp.net-signalr.htm
  6. http://cafe.daum.net/aspdotnet/O57m/115?docid=8C6QO57m11520130325023137
  7. http://www.asp.net/signalr/overview/getting-started/supported-platforms
  8. http://testswarm.signalr.net/user/signalr


목차
  1. Polling - 있어?
    [ASP.NET MVC] - Real time Apps - Polling
  2. LongPolling - 있으면 보내줘!
    [ASP.NET MVC] - Real time Apps - LongPolling
  3. SSE ( Server Send Events ) - 있으면 보내줘 기다릴께~ 
    [ASP.NET MVC] - Real time Apps - SSE ( Serve Sent Events )
  4. WebSocket - 어! 왔네~
    [ASP.NET MVC] - Real time Apps - WebSocket
  5. SignalR - over WebSocket ( MS Platform )
    [ASP.NET MVC] - Real time Apps - SignalR over WebSocket


 이 포스트에 있는 내용이 언제나 확실한 정답은 아닙니다. 진실이라고 생각해 왔던 전제가 시간의 지남에 따라 들어나지 않았던 다른 이면 때문에 좋은 방향으로 이끌어 낼 수 있는 역할로 변환 되는게 역사적으로도 많은 증명 있었습니다. 그렇지만 저는 현재 상황에서 최선의 답을 찾고자 노력하였으며 이 글을 읽는 다른 분들에게 다음 길을 갈 수 있도록 도와주는 디딤돌이 되고자 노력하고자 포스팅을 통해 공유하고자 하는 것입니다. 그리고 프로그래머라는 타이틀을 달고 살아야 한다면 "왜"라는 의문을 항상 가지고 다니면서 자신의 위치에 안주하지 않고 항상 노력하는 모습으로 살아 가고자 합니다. 언제든 지적이나 오류가 있으면 피드백 부탁 드리겠습니다.

ing™       



ASP.NET SignalR 소개


'http://signalr.net/' 에서는 SignalR을 아래와 같이 소개하고 있다.


ASP.NET SignalR is a new library for ASP.NET developers that makes it incredibly simple to add real-time web functionality to your applications. What is "real-time web" functionality? It's the ability to have your server-side code push content to the connected clients as it happens, in real-time. 


 말하자면 ASP.NET SignalR은 어플리케이션에 매우 간단하게 실시간 웹 기능을 만들 수 있도록 해주는 ASP.NET 개발자를 위한 라이브러리이다. 실시간 웹 기능이란? 서버 사이드에서 실시간으로 일어난 일을 연결된 클라이언트에게 내용을 능동적으로 전달하는 것이다. 즉 SignalR은 즉각적인 사용자와의 상호작용과 실시간 데이터 갱신이 필요한 웹 응용 프로그램 개발을 지원하기 위한 라이브러리이다. 예로 대시보드에서 다른 시스템을 모니터링을 할 때 즉각적으로 변하는 값을 브라우저의 그래프에 즉시 반영하는 시나리오에 적합하다.


 SignalR은 실시간 응용 프로그램 개발 과정을 WebSocket를 이용한 개발보다 더 단순화시켜 줍니다. ASP.NET의 서버 라이브러리와 SignalR에서 같이 제공되는 자바스크립트 클라이언트 라이브러리를 통해서 WebSocket을 직접 사용하는 것보다 더 추상화 시킨 라이브러리이다. '그림8'과 같이 추상화된 라이브러리로 API를 사용하면 WebSocket을 지원하는 클라이언트 브라우저에서는 WebSocket를 통해 서버와 통신하고, 그렇지 않을 경우에는 대체되는 통신 기법으로 바뀌어 서버와의 통신을 유지하도록 해준다. 




[그림11] SignalR 통신




본격적으로 SignalR을 살펴 보기 전에 시스템적인 요구 사항을 점검해 보도록 하자



서버 시스템 요구 사항


지원되는 서버 리스트


  • Windows Server 2012
  • Windows Server 2008 r2.
  • Windows 8
  • Windows 7
  • Windows Azure


지원되는 IIS (웹 컨테이너)


  • IIS 8 or IIS 8 Express.
  • IIS 7 and 7.5. Support for extensionless URLs is required.
  • IIS 통합모드


클라이언트 요구 사항


브라우저 버전


  • Microsoft Internet Explorer versions 8, 9 and 10. Modern, Desktop, and Mobile versions are supported.
  • Mozilla Firefox: current version - 1, both Windows and Mac versions.
  • Google Chrome: current version - 1, both Windows and Mac versions.
  • Safari: current version - 1, both Mac and iOS versions.
  • Opera: current version - 1, Windows only.
  • Android browser

브라우저에서 jQuery version 1.6.4, 1.7.2, 1.8.2, or 1.9.1


자신의 브라우저가 지원이 되는지 알아 볼 수 있는 사이트가 있으니 자세한 정보는 이곳에서 알아 보기 바란다.

http://testswarm.signalr.net/user/signalr





[그림12] Nuget Package Manager에서 SignalR을 검색한 결과 화면


 이제 개발에 필요한 라이브러리를 추가 하자. Nuget을 통해 SignalR로 검색하면 '그림12'와 같은 화면을 확인할 수 있을 것이다. 이 중에서 'Microsoft ASP.NET SignalR'을 선택하고 설치하면 자동으로 Visual Studio에 필요한 DLL들이 추가가 될 것이다. 그런다음 Global.asax.cs 파일을 열어서 '코드12'와 같이 'RouteTable.Routes.MapHubs();'를 Application_Start에 추가 하고 저장 후 닫아 버리자

protected void Application_Start() {     // SignalR 세팅     RouteTable.Routes.MapHubs(); ... (기존 코드)

}

[코드12] Global.asax.cs 에 추가된 초기화 코드


 위 코드는 SignalR이 ASP.NET에서 초기화가 되도록 세팅하는 것이며 Global.asax.cx의 Application_Start 메소드는 웹 서버가 처음 기동될 때 단 한번만 실행이 된다. 그러므로 SignalR 관련 초기화는 한번만 이뤄지게 된다.


<!-- SignalR로 통신하여 받은 데이터를 반영할 수 있는 DOM -->
<ul id="messages"></ul>
 
@using (Ajax.BeginForm("PostMessage"new AjaxOptions())) { 
    <p>
        Say : @Html.TextBox("messageText")
        <input type="submit" />
    </p>
}
 
@section scripts {
    <script src="~/Scripts/jquery.signalR-1.0.1.js" type="text/javascript"></script>
    <script src="~/signalr/hubs" type="text/javascript"></script>
    <script type="text/javascript">
        $(function () {
            // Form의 Submit 이벤트  통제
            $("form").submit(function () {
                var text = $('#messageText').val();
                // Hub를 통해 SignalR 통신으로 서버에 보낸다.
                messagesHub.server.send(text);
                $('#messageText').val('').focus();
                return false;
            });
 
            // SiglalR/Hubs에서 Generated된 javascript 코드를 할당
            var messagesHub = $.connection.messages;
 
            // SignalR에서 Hub를 통해  메세지를 받는다.
            messagesHub.client.addMessage = function (messageFromServer) {
                $('<li>').text(messageFromServer).appendTo("#messages");
            }
 
            // SignalR 시작
            $.connection.hub.start();
        });
    </script>
}

[코드13] SignalR이 브라우저에서 실행될 클라이언트 사이드 코드


1. <script src="~/Scripts/jquery.signalR-1.0.1.js" type="text/javascript"></script> : SignalR 관련 라이브러리를 추가하면 jQuery를 확장한 자바스크립트 라이브러리가 추가되어 있을 것이다. 웹 페이지에서 사용할 수 있도록 추가하는 것이다.

2. <script src="~/signalr/hubs" type="text/javascript"></script> : 서버 코드상에서 Hub를 상속받은 Messages 클래스에 대해서 Generated하여 자바스크립트 코드를 만든었으며 서버에서 추가한 메소드가 자바스크립트에서 실행이 되도록 하고 있다. 자세한 사항은 밑에서 한번더 다루도록 하겠다.

3. var messagesHub = $.connection.messages : SignalR의 자바스크립트 라이브러리가 연결할 Hub 객체를 할당한다.

4. messagesHub.server.send(text) : text 메시지를 서버에 보내준다.

5. messagesHub.client.addMessage : 서버에서 보내준 메시지를 처리하는 이벤트를 설정한다. 여기서는 화면에 보여주는 로직만 코딩되어 있다.


서버측 코드에 대해서 작성할 차례인데 생각보다 간단한 코드로 이뤄진다.

/// <summary> /// 컨트롤러 클래스 /// </summary> public class SignalRTestController : Controller {     //     // GET: /SignalR/     public ActionResult Index()     {         @ViewBag.Message = "SignalR Test";         return View();     } } /// <summary> /// SignalR의 기능을 담당할 Messages, 클라이언트에서 올려준 메세지를 모든 클라이언트에 뿌려주는 역할을 한다. /// </summary> public class Messages : Hub {     public void Send(string message)     {         Clients.All.addMessage(message);     } }

[코드14] SignalR의 서버 사이드 코드


1. SignalRTestController : 단순히 웹 페이지를 보여주기 위한 코드 밖에 없다.

2. public class Messages : Hub : 이 코드가 SignalR의 핵심이다. 여기에서 추가로 코드가 자바스크립트로 Generated로 되어 브라우저에서도 사용할 수 있게 변환이 된다.

3. Clients.All.addMessage(message) : 받은 메시지를 연결된 모든 클라이언트에게 보내주는 코드다.



이제 코드 설명은 다 끝났지만 한간지 의문점이 남게 될 것이다. Generated되어 자동으로 실행이 되도록 한다고 하였지만 무엇이 어떻게 생성이 되고 실행이 되는지는 모른다. 일반적으로는 몰라도 SignalR에서 자동으로 뒷단에서 많은 일들을 하고 있기 때문에 편리하게 브라우저의 HTML5에 제한을 생각하지 않고 편리하게 사용만 하면 된다. 그렇지만 SignalR을 더 많이 이해하기 위해 자바스크립트 소스를 분석하게 되었다. 아래 '코드14'가 브라우저에서 Generated된 자바스크립트 코드다. 너무 길어 일괄적인 코드는 생략하고 중요한 코드만 남겨 두었다. 


[코드15] /signaR/Hubs에서 만들어진 자바스크립트 코드


 자동으로 생성된 코드는 서버에서 Hub를 상속 받은 Messages의 분석하여 Javascript를 만든 것이다. 서버의 'Send' 메소드가 자바스크립트의 send: function (message) { }로 변환된 것을 확인 할 수 있다. 이런 방식으로 서버의 코드를 자바스크립트에서 직접 사용할 수 있도록 Proxy를 만들어서 브라우저에 보내주는 것이다. 이제 모든 코드에 대해서 살펴 보았으니 결과를 확인해 보도록 하자.




[그림13] SingalR 실행 결과 화면 ( 위쪽이 Chrome, 아래쪽이 IE10 )



1. IE에서 메시지를 'IE10에서 보내는 SignalR 메시지' 입력하고 서버에 전송한다. - 실시간으로 크롬에서 확인된다.

2. 크롬에서 메시지를 'Chrome에서 보내는 SignalR 메시지' 입력하고 서버에 전송한다. - 실시간으로 IE에서 확인된다.


위와 같이 실시간으로 보내지는 메시지를 브라우저에서 받아 처리하도록 한다. 여기까지는 WebSocket와 별 다를게 없어 보인다. HTML5의 WebSocket를 지원하지 않는 브라우저를 재현하기 위해 IE의 '관리자 도구'를 이용하여 모드를 하위 버전으로 수정하여 테스트를 진행하여 서버와이 통신이 어떻게 변경이 되는지 확인해 보도록 하겠다.



IE에서 F12로 관리자 모드를 활성화 한다. 이곳에서 네트워크 탭으로 가서 캡춰 시작 버튼을 눌러 네트워크 트래픽이 잡아 내도록 한다. 그리고 브라우저 모드를 IE10에서 IE9으로 변경하면 아래와 같은 결과를 확인 할 수 있다.



[그림14] IE의 관리자 도구 화면


이제부터 브라우저는 IE10이지만 내부적으로는 IE9과 같은 방식으로 동작하게 된다. IE9은 WebSocket를 지원하지 않아 웹 소켓 통신을 하지 못하는데 어떻게 실시간으로 값을 받아 올 수 있을까? 이건 네트워크 트래픽에 잡힌 '/signalr/connect?transport=foreverFrame ...' Url 주소를 보면 해답을 찾을 수 있다. ForeverFrame으로 서버에 계속 연결되어 있는 상태가 되어 서버에서 Flush된 데이터를 브라우저에서 받는 것이다. 그래서 네트워크 결과에 보면 계속 '보류중' 이라고 나오는 것이다. 이렇게 SignalR을 사용하면 WebSocket만을 사용하여 개발하는 것 보다 브라우저의 제약에 좀더 자유로울 수 있게 되고 추상화된 API를 제공하므로 개발의 일관성을 유지할 수 있게 된다.


지금까지 브라우저에서 서버와 통신하는 여러가지 방법중에 대표적인 기술과 최신에 나온 WebSocket 그리고 통신 기술들을 아우르는 추상화 시킨 라이브러리인 SignalR이나 Socket.IO에 대해서 간략하게 나마 알아 보았다. 어떤 기술을 선택하여 개발할지는 각각의 개발 환경이나 제약 사항에 따라 취사 선택을 해야 할 것이다. 이제 부터는 각자 자신의 몫이다. 자신의 것으로 만들고 적용하여 보다 발전된 방향으로 가야하는 짐을 여러분에게 맡기는 것이다. 


소스 코드 자체에 주석과 직관적인 코딩으로 충분히 파악이 가능할 것으로 예상하므로 별도의 설명을 생략하도록 하겠습니다. 포스트의 내용이 장황한 설명 보다는 주석과 소스코드 자체 만으로도 이해할 수 있도록 하기 위해 노력하였습니다. 실 개발에서도 적용할 수 있도록 간단하면서도 현실적인 예제 프로그램을 통해 각 소스를 만들고 이해 시키고자 하였으며 실무에 필요한 개발요구 사항들을 해결 하는데 도움이 되고자 노력하였습니다. 그리고 소스와 같이 있는 주석을 이용해 nDoc이나 별도의 자동 Document 제작 유틸로 API 문서를 만드는 데에도 도움이 되었으면 한다. 
※ DOC에 대한 프로그램 정보 Util link

ing™       




Windows 8.1 RTM and Windows 2012 R2 RTM


참조 URL
  1. http://blogs.msdn.com/b/stevengu/archive/2013/09/09/download-windows-8-1-rtm-visual-studio-2013-rc-and-windows-server-2012-r2-rtm-today.aspx
  2. http://msdn.microsoft.com/en-US/windows/apps/hh690938



MSDN을 구독하고 있는 분들은 다운받을 수 있도록 하였습니다. 









Real time Apps #5 - WebSocket


참조 URL
  1. http://dev.w3.org/html5/websockets/
  2. http://tools.ietf.org/html/rfc6455
  3. http://www.infoq.com/articles/Web-Sockets-Proxy-Servers
  4. http://en.wikipedia.org/wiki/Protocol_overhead
  5. http://html5please.com/
  6. https://github.com/gimite/web-socket-js - WebSocket polyfill library
  7. http://weblogs.asp.net/dwahlin/archive/2013/04/13/building-an-html5-web-sockets-server-with-asp-net-4-5.aspx
  8. http://jsperf.com/choosing-websocket-vs-mozwebsocket
  9. https://developer.mozilla.org/en-US/docs/WebSockets
  10. https://developer.mozilla.org/ko/docs/WebSockets

 

목차
  1. Polling - 있어?
    [ASP.NET MVC] - Real time Apps - Polling
  2. LongPolling - 있으면 보내줘!
    [ASP.NET MVC] - Real time Apps - LongPolling
  3. SSE ( Server Send Events ) - 있으면 보내줘 기다릴께~ 
    [ASP.NET MVC] - Real time Apps - SSE ( Serve Sent Events )
  4. WebSocket - 어! 왔네~
    [ASP.NET MVC] - Real time Apps - WebSocket
  5. SignalR - over WebSocket ( MS Platform )
    [ASP.NET MVC] - Real time Apps - SignalR over WebSocket


 이 포스트에 있는 내용이 언제나 확실한 정답은 아닙니다. 진실이라고 생각해 왔던 전제가 시간의 지남에 따라 들어나지 않았던 다른 이면 때문에 좋은 방향으로 이끌어 낼 수 있는 역할로 변환 되는게 역사적으로도 많은 증명 있었습니다. 그렇지만 저는 현재 상황에서 최선의 답을 찾고자 노력하였으며 이 글을 읽는 다른 분들에게 다음 길을 갈 수 있도록 도와주는 디딤돌이 되고자 노력하고자 포스팅을 통해 공유하고자 하는 것입니다. 그리고 프로그래머라는 타이틀을 달고 살아야 한다면 "왜"라는 의문을 항상 가지고 다니면서 자신의 위치에 안주하지 않고 항상 노력하는 모습으로 살아 가고자 합니다. 언제든 지적이나 오류가 있으면 피드백 부탁 드리겠습니다.

ing™       


 이제까지 단 방향 통신에 대해서 살펴 봤다면 지금 부터는 양 방향 통신을 지원하는 WebSocket에 대해서 알아 보고자 한다. 표준 WebSocket의 API는 W3C에서, 프로토콜은 IETF(Internet Engineering Task Force)에서 HTML5의 하위로 재정을 하고 있으며 지금도 현재 진행형이다. 그리고 WebSocket은 HTTP와 마찬가지로 80번 포트를 통해 웹 서버에 연결한다. HTTP 프로토콜의 버전은 1.1이지만 아래 헤더에서 보듯이 Upgrade 헤더를 이용하여 웹 서버에 접속한다. 


[HTTP 헤더 1] Client to Server WebSocket 헤더 정보



[HTTP 헤더 2] Web Server to Client 헤더 정보


[HTTP 헤더 3] HTTP Connect 메소드 헤더 정보


 브라우저는 "Upgrade: WebSocket" 헤더와 함께 랜덤하게 생성한 키를 서버에 보내고 웹 서버는 이 키로 토큰을 생성하여 브라우저에 돌려준다. 위 헤더 정보는 WebSocket지원 버전에 따라 헤더 정보는 달라 질 수 있다. 이런 방식으로 handshaking을 하여 WebSocket을 연결하면 Protocol Overhead 방식으로 웹 서버와 브라우저가 WebSocket 통신을 하게 된다. Protocol Overhead 방식은 메타 데이터와 네트워크 라우팅 기법으로 여러 TCP 커넥션을 생성하지 않고 하나의 80번 포트의 TCP 커넥션을 사용하여 연결하고, 별도의 헤더로 논리적인 데이터 흐름 단위를 사용하여 여러 개의 가상 커넥션을 사용하는 효과를 가져오는 방식이다. ( Protocal Overhead는 일종의 공유기라 생각하면 쉬울것이다. 하나의 공인 IP를 가지고 내부적으로 여러대의 내부 IP에서 나눠 사용하듯이 말이다.) 이런 방식으로 HTTP와 같은 포트를 사용하여 방화벽이 있는 환경에서도 별도의 설정 없이도 WebSocket을 사용 할 수 있도록 지원하고 있다.


 이제까지의 내용을 간단한 도식으로 WebSocket이 웹 서버와 통신하는 흐름을 '그림6'를 통해 간략적으로 살펴 보자.

[그림6] WebSocket 통신 방법


1. Client에서 서버에 연결 시도 한다. 

2. 연결 시 헤더에 Upgrade정보를 보내며 서버와 Handshaking을 하여 연결 한다.

3. 서버에서 발생된 이벤트가 있으면 WebSocket을 통해 브라우저에 보낸다.

4. 연결 종료시까지 3단계를 수행 한다.


위 순서의 2번에 대해서  '그림7'과 같이 도해식으로 좀더 자세히 살펴 보자.

[그림7] WebSocket 도해식


1. Client가 서버에게 요청을 하면서 헤더에 Upgrade, WebSocket.Version, Key... 등을 같이 보내준다.

2. 서버는 자신이 응답할 수 있는 웹소켓이고 버전이 맞으면 Token을 내려 보낸다.

3. 클라이언트는 이 토큰을 가지고 웹 서버와 Protocal Overhead 방식으로 통신을 하게 된다.


 이런 방식으로 브라우저와 웹 서버가 뒷단에서 수행하여 웹 소켓 연결이 되도록 한다. 이제 준비가 되었으니 가볍고 빠른 방식으로 웹 서버에서 필요한 데이터를 주고 받으면 될 것이다.


 이제 클라이언트를 담당하는 브라우저에 대해서 점검해 봐야 할 것이다. 그렇지만 아직까지 모든 브라우저에서 지원하는 방식은 아니다. 아래 '그림8'와 같이 WebSocket를 지원하는 브라우저를 확인 해 보자.


[그림8] WebSocket 지원 브라우저

http://caniuse.com/#feat=websockets 참조 )


 IE는 10 이상부터 지원이 되고 있으며 파이어 폭스(19+)나, 크롬(25+)도 지원하고 있다. IE는 비교적 가장 최신 버전에서만 지원하고 있으므로 개발할 때 염두에 두고 진행해야 할 것이다. 한국의 제한된 시장에서는 아직도 IE 10 이하 버전을 사용하고 있는 사용자들이 많기 때문에 개발시 검토를 잘 하고 진행해야 할 것이다. 하지만 후에 검토할 signalR( 또는 Socket.IO)을 통해서 브라우저 호환성을 극복하여 브라우저마다 다른 호환 범위를 하나의 프로그래밍 개발 접근 방식으로도 해결할 수 있는 방법이 있으니 너무 일찍 좌절감을 맞보지 않기를 소망한다. 희망을 가지고 코드 사이드에서 WebSocket를 진행하도록 하겠다.


 아래 '코드7'는 브라우저에서 WebSocket의 지원하는 메소드 및 간단한 코드 조각이다. (이 코드를 확장하여 개발 범위에 맞게 가감하여 사용하면 될 것이다.)


[코드7] 브라우저에서 WebSocket을 사용하는 메소드 예제


 클라이언트에서의 웹 소켓과 관련된 코드는 '코드7'이 전부라고 알고 있으면 되겠다. 이 작은 코드가 웹 소켓에서 발생하는 모든 이벤트를 보여주고 있다. 이제 이 작은 코드 조각으로 웹 서버를 통해 어떻게 응용이 되는지 살펴 보자. 아래 '코드8'은 .Net 진영에서 제공되는 ASP.NET MVC와 Razor 뷰 문법으로 구성되었으며 서버 사이드의 자체 문법 보다는 전체적인 흐름을 파악하는데 중점을 두고 코드를 살펴 보기를 바란다.


<!-- WebSocket으로 받은 데이터를 반영할 수 있는 DOM --> <ol id="messages"></ol> @using (Ajax.BeginForm("PostMessage"new AjaxOptions())) {      <p>         Say : @Html.TextBox("messageText")         <input type="submit" />      </p> } @section scripts{     <script type="text/javascript">         $(function () {             $("form").submit(function () {                 var form = $(this);                 var txtMessageText = $(form.find('#messageText'));                 $.post('@Url.Action("PostMessage")', { 'messageText': txtMessageText.val() }, function () {                     txtMessageText.val('');                     txtMessageText.focus();                 });                 return false;             });             start();         });         var start = function () {             var wsImpl = window.WebSocket || window.MozWebSocket;             // 웹 소켓 초기화             window.ws = new wsImpl('ws://localhost:8181/', 'my-protocol');             ws.onmessage = function (evt) {                 $('<li>').text(evt.data).appendTo('#messages');             };             ws.onopen = function () {                 $('<li>').text('웹 소켓 연결 되었습니다.').appendTo("#messages");             };             ws.onclose = function () {                 $('<li>').text('웹 소켓이 닫혔습니다.').appendTo("#messages");             }         }     </script> }

[코드8] WebSocket의 브라우저에서 실행될 클라이언트 사이드 코드


1. @using (Ajax.BeginForm("PostMessage", new AjaxOptions())) : form 테그를 완성하는 Razor 문법이다. 여기에서 '@' 구문은 Razor 문법의 시작을 알리는 예약어다.

2. $(function () { $("form").submit(function () { : 는 1번에서 선언된 테그에서 발생하는 submit 이벤트를 받아서 페이지 이동을 하지 못하도록 하고 사용자가 입력한 값을 ajax로 통신하여 서버에 submit하도록 한다.

3. var wsImpl = window.WebSocket || window.MozWebSocket : 웹 소켓 객체를 생성한다. ( https://developer.mozilla.org/en-US/docs/WebSockets 사이트에서 보면 Gecko 6.0에서 개명되어 WebSocket와 MozWebSocket이 일부 브라우저와 버전에 따라서 공전할 수 있기 때문에 사용한 코드다 ) 

4. window.ws = new wsImpl('ws://localhost:8181/', 'my-protocol') : 서버에서는 8181 포트로 초기화를 할 것이기에 이포트를 설정하였고 뒤에 인자는 임의의 값으로 설정하면 된다. 이 코드를 통해 웹 서버와 통신할 수 있도록 초기화를 한것이다. 이 부분에서 서버와의 통신은 80번으로 하지만 내부적으로는 8181 포트를 사용하는 것처럼 동작하게 되는 것이다.

5. onmessage, onopen, onclose : 이름으로 유추할 수 있듯이 서버에서 보내주는 메세지가 있거나 상태가 변경이 되면 해당 function이 실행이 되도록 이벤트를 연결한 것이다. 이벤트가 발생되어 실행이 되면 messages의 id를 가진 '<ol id="messages"></ol>' 테그의 하위 노드에 li가 추가되면서 메시지가 보여질 것이다.




var wsImpl = window.WebSocket || window.MozWebSocket;


여담이지만 위의 작은 코드에도 성능 향상을 기법이 들어가 있다. 전역 객체로 할당 받는 것과 지역 객체로 할당받는 것에 대해서 속도 측정을 해 놓은 사이트가 있다. 'http://jsperf.com/choosing-websocket-vs-mozwebsocket'에서 Performance를 직접 측정할 수 있다.


아래 코드에 대해서 측정할 수 있으며 'Run Test' 버튼을 통해 측정 한다.


1. window.WebSocket = window.WebSocket || window.MozWebSocket;

2. var WebSocket = window.WebSocket || window.MozWebSocket;


Chrome에서 1번 코드와 2번 코드의 성능에 대해서 측정을 하면 아래와 같은 결과가 나오고 있다.
(측정값은 브라우저와 컴퓨터 성능에 따라 다른 결과가 도출 될 수도 있다.)






 이제 클라이언트인 브라우저 코드를 살펴 보았다면 서버측 코드를 살펴 보자. 살펴 보기에 앞서 아래 코드는 MVC 패턴의 Controller 역할을 맡은 소스 코드라는 것을 염두에 두고 살펴보기 바란다.



코드를 작성하기 전에 프로젝트 솔루션에 추가해야 하는 외부 참조 Dll이 있다. 

'https://github.com/statianzo/Fleck'에서 진행되는 웹 소켓 프로젝트이며 관련 소스를 다운 받아 분석할 수 있다. 그렇지만 간단하게 사용하거나 아래 소스코드를 실행해 보기를 원한다면 NuGet를 통해서 'Fleck'로 검색 후 추가하면 된다.


#region Fields
/// <summary>
/// 웹 소켓 초기화시 중복 초기화가 되지 않도록 잠금 역할하는 객체
/// </summary>
private static object webSocketLock = new object();
 
/// <summary>
/// 연결된 클라이언트들의 커넥션 리스트 객체
/// </summary>
private static List<IWebSocketConnection> allSockets = null;
 
/// <summary>
/// 웹 소켓 호스트 역할 객체
/// </summary>
private static WebSocketServer server = null;
#endregion
 
/// <summary>
/// 생성자
/// </summary>
public WebSocketController()
{
    #region WebSocket 초기화
    if (allSockets == null)
    {
        lock (webSocketLock)
        {
            if (allSockets == null)
            {
                allSockets = new List<IWebSocketConnection>();
                server = new WebSocketServer("ws://localhost:8181");
 
                InitWebsocket();
            }
        }
    }
    #endregion
}
 
public ActionResult Index()
{
    @ViewBag.Message = "WebSocket Test";
    return View();
}
 
/// <summary>
/// 메세지 받아서 waiting 풀어 주기
/// </summary>
/// <param name="messageText">입력 받은 값</param>
public void PostMessage(string messageText)
{
    // 웹 소켓에 받은 메세지를 보내주기
    foreach (var socket in allSockets)
    {
        socket.Send(messageText);
    }
}
 
/// <summary>
/// 웹 소켓 초기화
/// </summary>
[NonAction]
public void InitWebsocket()
{
    server.Start(socket =>
    {
        // 웹 소켓 연결 할 때
        socket.OnOpen = () =>
        {
            allSockets.Add(socket);
        };
 
        // 웹 소켓이 닫을 때
        socket.OnClose = () =>
        {
            Console.WriteLine("Close!");
            allSockets.Remove(socket);
        };
 
        // 웹 소켓에서 메세지 전송 할 때
        socket.OnMessage = message =>
        {
            allSockets.ToList().ForEach(s => s.Send("Echo: " + message));
        };
    });
}

[코드9] WebSocket의 서버 사이드 코드


1. private static object webSocketLock = new object() : 쓰레드에서 동기화를 구현하기 위한 객체이며 여러개의 쓰레드에서 하나의 자원을 동시 접근시 순차적으로 접근이 가능하도록 Lock를 걸어주는데 사용한다.

2. private static List<IWebSocketConnection> allSockets = null : 하나의 WebSocket 연결을 관리 하는 리스트 객체다. 이 객체에는 클라이언트를 구분하고 그룹을 짓고 메세지를 보내는 역할을 하는 리스트를 나타낸다.

3. private static WebSocketServer server = null : 실질적으로 WebSocket의 핵심 로직이 들어간 서버 객체다. 이 객체가 클라이언트와 WebSocket 방식으로 통신을 한다.

4. new WebSocketServer("ws://localhost:8181") : 웹 소켓을 localhost의 8181 포트로 동작하도록 한다. - 프로토콜 오버헤드 방식으로 동작하므로 외부에서는 80으로 접속하지만 내부적으로는 8181포트로 동작한다.

5. PostMessage(string messageText) : 브라우저에서 submit시 받아 처리하는 코드로 메시지를 받으면 접속된 모든 클라이언트에 동일한 메시지를 전달하도록 되어 있다.

6. [NonAction] InitWebsocket() : NonAction은 브라우저에서 직접적으로 InitWebsocket를 접근 하지 못하도록 하는 속성이다. 

7. socket.OnOpen = () => { allSockets.Add(socket); } : WebSocket이 브라우저와 handshaking이 이뤄지고 나서 연결이 될 때 발생되는 이벤트다. 접속한 브라우저의 연결된 정보를 관리 하도록 리스트에 저장한다.

8. socket.OnClose = () => { allSockets.Remove(socket); } : 연결된 WebSocket이 닫히면 관리되는 리스트에서도 제거한다.

9. socket.OnMessage = message => {  } : 관리되는 리스트에게 같은 메세지를 일괄적으로 클라이언트에게 웹소켓으로 보내준다.



 이제 전체 소스를 살펴 보았으니 '그림9'을 통해 결과를 확인 해 보도록 하자.



[그림9] WebSocket 결과 화면 ( 위쪽이 Chrome, 아래쪽이 IE10 )



1. 처음 Chrome 브라우저를 통해 접속을 하고 '첫번째 웹 소켓 통신'을 입력하고 버튼을 눌러 서버에 전송 하였다.

2. IE10으로 같은 주소를 접속하고 'IE에서 보내는 웹 소켓 메시지'를 입력하고 버튼을 눌러 서버에 전송 하였다.

    - Chrome에서도 동일한 메시지가 실시간으로 확인 할 수 있다.

3. Chrome에서도 'Chrome에서 보내는 웹 소켓 메시지'를 입력하고 버튼을 눌러 서버에 전송 하였다.

    - IE에서도 동일한 메시지가 실시간으로 확인 할 수 있다.



 이번에는 WebSocket의 통신 흐름 잡아 내 보도록 하자.  아래 '그림10'처럼 F12를 눌러 개발자 도구를 활성화 시키고 'WebSocket'를 선택하고 브라우저에서 값을 입력하여 서버에 보내면 웹 소켓 통신으로 받은 패킷을 아래처럼 잡을 수 있다. 


[그림10] Chrome에서 WebSocket의 패킷을 잡아낸 그림


 이 방법으로 웹 소켓과의 통신을 추적할 수 있게 되었다.



이제 웹 소켓에 대해서 대략적으로나마 살펴 보았다. 생각보다 코드의 양은 많지 않았지만 생소할 수도 있어서 코드 주석과는 별개로 밑에 세부 설명을 추가 하였으니 좀더 쉽게 이해가 되었으면 하는 바램입니다. 눈으로만 지나치시지 마시고 한번씩이라도 실습을 통해 나의 경험으로 체득하심을 극히 권해 드리며 프로그램 만으로도 행복할 수 있는 세상이 오기를 바라며 이번 포스트를 마칩니다.



 다음에 소개해 드릴 signalR은 지금보다 더 쉽고 편한 방법으로 개발 할 수 있는 라이브러리에 대해서 알아 보도록 하겠습니다. 흥미로운 signalR을 기대해 주세요~



 Guillermo Rauch가 만든 Socket.IO( http://socket.io/ )는 WebSocket, FlashSocket, Ajax Long Polling, Ajax Multipart streaming, Forever Iframe, JSONP Polling을 하나의 API로 추상화 해서 제공하고 있다. 즉 브라우저와 웹 서버의 종류를 파악하여 가장 적합한 기술을 자동 선택하여 사용하는 방식을 제공한다. 간다히 케이스를 정하자면 WebSocket를 지원하지 않는 브라우저에서도 상관 없이 같은 개발 방식으로 개발할 수 있도록 지원한다는 것이다. 그렇지만 아직까지는 Node.js 플랫폼 위에서만 동작하는 제약이 있다.


[코드10] Socket.IO in Browser


[코드11] Socket.IO on Node.js


 이로써 Socket.io를 사용할 준비는 모두 끝났다. 브라우저에서 페이지를 열면 콘솔에는 "{ server : 'hello world!' }"가서버 콘솔에는 "{ browser : 'data' }"가 출력되는 것을 확인할 수 있을 것이다. Socket.io에 대해서 깊게 알고 싶다면 "http://socket.io/"에서 가셔서 확인할 수 있을 것이다. 물론 Windows에서도 IISNodehttps://github.com/tjanczuk/iisnode ) 모듈을 통해서 node에 대한 개발 및 테스트를 할 수 있다.






소스 코드 자체에 주석과 직관적인 코딩으로 충분히 파악이 가능할 것으로 예상하므로 별도의 설명을 생략하도록 하겠습니다. 포스트의 내용이 장황한 설명 보다는 주석과 소스코드 자체 만으로도 이해할 수 있도록 하기 위해 노력하였습니다. 실 개발에서도 적용할 수 있도록 간단하면서도 현실적인 예제 프로그램을 통해 각 소스를 만들고 이해 시키고자 하였으며 실무에 필요한 개발요구 사항들을 해결 하는데 도움이 되고자 노력하였습니다. 그리고 소스와 같이 있는 주석을 이용해 nDoc이나 별도의 자동 Document 제작 유틸로 API 문서를 만드는 데에도 도움이 되었으면 한다. 
※ DOC에 대한 프로그램 정보 Util link

ing™       



Moment.js

( 시간이나 날짜 관련 라이브러리 )


참조 URL
  1. http://momentjs.com/
  2. https://github.com/moment/moment
  3. http://www.devcurry.com/2013/08/using-jquery-and-momentjs-in-aspnet-mvc.html#.Uikzr7iwewU
  4. http://www.codersgrid.com/2013/07/13/introduce-to-moment-js-and-moment-timezone/



시간이나 날짜 관련 라이브러리다.

웹 페이지에서 언어에 따르는 날짜 포맷을 지원해야 한다면 Moment.js를 사용해 보면 좋을 것이다.






Windows 8에서 원격 연결이 되지 않을 때

( Windows 8 RP with Microsoft Account fails )


참조 URL
  1. http://social.technet.microsoft.com/Forums/en-US/859684c3-59f6-410a-bc9e-d9cdd666ae58/remote-desktop-into-windows-8-rp-with-microsoft-account-fails
  2. http://support.microsoft.com/kb/941641

 

  

 

Windows8에서 원격 연결시 제대로 아이디와 패스워드를 입력하였는데도 연결이 되지 않는다.

 

 

[그림1] 원격 연결 실패 화면

 

 

 

 

아래와 같은 사항으로 문제를 해결 할 수 있습니다.

 

 

MS 가이드 절차

 

이 문제를 해결하려면 원격 데스크톱 연결 6.0에서 새로운 기능을 해제하여 원격 데스크톱 연결 5.x의 기능으로 되돌립니다. 이렇게 하려면 다음과 같이 하십시오.

  1. 시작, 실행을 차례로 누르고 mstsc.exe를 입력한 다음 확인을 누릅니다.
  2. 옵션을 누른 다음 일반 탭을 누릅니다.
  3. 다른 이름으로 저장을 누른 다음 파일 이름 상자에 파일 이름을 입력합니다.
  4. 원격 데스크톱 파일을 저장할 위치를 선택하고 저장을 누른 다음 취소를 누릅니다.

    참고 저장된 파일의 확장명은 .rdp입니다.
  5. 시작, 실행을 차례로 누르고 notepad를 입력한 다음 확인을 누릅니다.
  6. 파일 메뉴에서 열기를 누릅니다.
  7. 파일 형식 목록에서 모든 파일을 누릅니다.
  8. 찾는 위치 목록에서 4단계에서 저장한 파일을 찾아 누른 다음 열기를 누릅니다.
  9. 다음과 유사한 줄을 찾습니다.
    authentication level:i:n
    참고 n 자리 표시자는 현재 인증 수준을 나타냅니다.
  10. 인증 수준을 0으로 변경하여 줄이 다음과 같이 되도록 합니다.
    authentication level:i:0
    참고 인증 수준을 0으로 설정하면 RDP 6.0에서 서버 인증을 확인하지 않습니다.
  11. 파일의 끝에 다음 줄을 추가합니다.
    enablecredsspsupport:i:0
    참고 이 줄이 있으면 원격 데스크톱 연결을 설정하기 전에 자격 증명을 제공할 필요가 없습니다.
  12. 파일 메뉴에서 저장을 누릅니다.

원격 데스크톱 연결을 사용하여 연결하려면 12단계에서 저장한 파일을 실행합니다.

참고 이러한 단계를 수행하면 원격 데스크톱 연결 6.0에서 제공하는 새로운 보안 기능이 제거됩니다. 또한 원격 데스크톱 연결 6.0이 시스템 속성에서 네트워크 수준 인증이 있는 원격 데스크톱을 실행 중인 컴퓨터에서만 연결 허용 옵션을 사용하는 Windows Vista 기반 컴퓨터와 호환되지 않습니다.
 

 

 

위와 같은 설명은 너무 장황 스럽고 이해 하기도 힘들다면 rdp로 저장하고 편집된 코드를 보도록 하자

 

screen mode id:i:2
use multimon:i:0
desktopwidth:i:1920
desktopheight:i:1080
session bpp:i:32
winposstr:s:0,1,2110,31,3390,1025
compression:i:1
keyboardhook:i:2
audiocapturemode:i:0
videoplaybackmode:i:1
connection type:i:7
networkautodetect:i:1
bandwidthautodetect:i:1
displayconnectionbar:i:1
enableworkspacereconnect:i:0
disable wallpaper:i:0
allow font smoothing:i:0
allow desktop composition:i:0
disable full window drag:i:1
disable menu anims:i:1
disable themes:i:0
disable cursor setting:i:0
bitmapcachepersistenable:i:1
full address:s: site.com:51201 ( 상황마다 다름 )
audiomode:i:0
redirectprinters:i:1
redirectcomports:i:0
redirectsmartcards:i:1
redirectclipboard:i:1
redirectposdevices:i:0
autoreconnection enabled:i:1
authentication level:i:2
prompt for credentials:i:1
negotiate security layer:i:1
remoteapplicationmode:i:0
alternate shell:s:
shell working directory:s:
gatewayhostname:s:
gatewayusagemethod:i:4
gatewaycredentialssource:i:4
gatewayprofileusagemethod:i:0
promptcredentialonce:i:0
use redirection server name:i:0
rdgiskdcproxy:i:0
kdcproxyname:s:
drivestoredirect:s:
enablecredsspsupport:i:0

 

 

위에서 빨간 글씨를 추가하고 한번더 다시 시도를 해보자.

 

 

 

 

+ Recent posts