ASP.NET SignalR 2.0: 자습서: SignalR 2.0 시작하기

등록일시: 2014-01-09 08:00,  수정일시: 2014-01-13 10:44
조회수: 6,452
이 문서는 ASP.NET SignalR 기술을 널리 알리고자 하는 개인적인 취지로 제공되는 번역문서입니다. 이 문서에 대한 모든 저작권은 마이크로소프트에 있으며 요청이 있을 경우 언제라도 게시가 중단될 수 있습니다. 번역 내용에 오역이 존재할 수 있고 주석은 번역자 개인의 의견일 뿐이며 마이크로소프트는 이에 관한 어떠한 보장도 하지 않습니다. 번역이 완료된 이후에도 대상 제품 및 기술이 개선되거나 변경됨에 따라 원문의 내용도 변경되거나 보완되었을 수 있으므로 주의하시기 바랍니다.

본문에서는 SignalR 2.0을 이용해서 실시간 챗 응용 프로그램을 작성하는 방법을 살펴보겠습니다. 먼저, 빈 ASP.NET 웹 응용 프로그램에 SignalR을 추가한 다음, 메시지를 전송하거나 출력하기 위한 HTML 페이지를 작성해볼 것입니다.

개요

본 자습서에서는 브라우저에 기반한 간단한 챗 응용 프로그램의 구축 과정을 살펴보면서 SignalR 2.0을 이용한 개발 방법을 소개하고자 합니다. 빈 ASP.NET 웹 응용 프로그램에 SignalR 라이브러리를 추가한 다음, 클라이언트에 메시지를 전송하기 위한 허브 클래스와, 사용자가 챗 메시지를 전송하거나 수신할 수 있는 HTML 페이지를 작성해 볼 것입니다. MVC 5와 MVC 뷰를 사용해서 챗 응용 프로그램을 작성하는, 본문과 비슷한 자습서인 ASP.NET SignalR 2.0: 자습서: SignalR 2.0과 MVC 5 시작하기도 참고해보시기 바랍니다.

노트: 본문에서는 SignalR 버전 2.0으로 응용 프로그램을 작성하는 방법을 살펴봅니다. SignalR 1.x와 2.0간의 차이점에 대한 더 자세한 정보들은 ASP.NET SignalR 2.0: SignalR 1.x 프로젝트를 2.0으로 업그레이드하기 문서와 Visual Studio 2013 Release Notes 문서를 참고하시기 바랍니다.

SignalR은 즉각적인 사용자 상호작용이나 실시간 데이터 갱신이 필요한 웹 응용 프로그램 구축을 지원하기 위한 오픈 소스 .NET 라이브러리입니다. 가령, 소셜 응용 프로그램이나 다중 사용자 게임, 업무 협업 응용 프로그램, 그리고 뉴스나 날씨 또는 금융 갱신 응용 프로그램 등이 이 부류에 해당됩니다. 이런 응용 프로그램들을 종종 실시간 응용 프로그램이라고 부릅니다.

SignalR은 실시간 응용 프로그램의 구축 과정을 단순하게 만들어줍니다. ASP.NET 서버 라이브러리와 자바스크립트 클라이언트 라이브러리의 조합을 통해서, 클라이언트와 서버 간의 연결 관리 작업이나 갱신된 콘텐트를 클라이언트에 푸시하는 작업 등을 손쉽게 만들어 줍니다. 실시간 기능을 추가로 구현하기 위해서 기존 ASP.NET 응용 프로그램에 SignalR 라이브러리를 추가할 수도 있습니다.

본문에서는 다음과 같은 SignalR 개발 작업들을 수행해볼 것입니다:

  • ASP.NET 웹 응용 프로그램에 SignalR 라이브러리를 추가합니다.
  • 콘텐트를 클라이언트에 푸시하기 위한 허브 클래스를 생성합니다.
  • 응용 프로그램을 구성하기 위한 OWIN 시작 클래스를 생성합니다.
  • 웹 페이지에서 SignalR jQuery 라이브러리를 사용해서 메시지를 전송하거나 허브로부터 갱신된 내용들을 가져와서 출력합니다.

다음 화면 이미지는 브라우저에서 실행되는 챗 응용 프로그램을 보여주고 있습니다. 각각의 새로운 사용자들은 코멘트를 포스트 할 수도 있고, 자신이 챗에 참여한 이후에 추가된 코멘트들을 볼 수 있습니다.

Chat instances

목차:

프로젝트 설정하기

이번 절에서는 Visual Studio 2013과 SignalR 버전 2.0을 사용해서 빈 ASP.NET 웹 응용 프로그램을 생성하는 방법을 살펴봅니다.

전제조건:

  • Visual Studio 2013. 만약, Visual Studio 2013을 보유하고 있지 않다면, ASP.NET Downloads에서 무료 Visual Studio 2013 Express Development Tool을 다운로드 받을 수 있습니다.

다음은 Visual Studio 2013을 사용해서 ASP.NET 빈 웹 응용 프로그램(ASP.NET Empty Web Application)을 생성한 다음, SignalR 라이브러리를 추가하는 과정을 보여줍니다:

  1. 먼저, Visual Studio에서 ASP.NET 웹 응용 프로그램을 생성합니다.

    Create web

  2. 새 ASP.NET 프로젝트(New ASP.NET Project) 대화 상자에서 Empty를 선택하고 확인(OK) 버튼을 클릭합니다.

    Create empty web

  3. 그리고, 솔루션 탐색기에서 마우스 오른쪽 버튼으로 프로젝트를 클릭하고 추가(Add) | 새 항목(New Item) 메뉴를 선택해서 새 항목 추가(Add New Item) 대화 상자를 띄운 다음, 웹(Web) 카테고리에서 SignalR 허브 클래스(v2)(SignalR Hub Class (v2))를 선택합니다. 허브 클래스의 이름을 ChatHub.cs로 지정하고 추가(Add) 버튼을 클릭합니다. 그러면, 새로운 ChatHub 클래스가 생성되고 SignalR을 지원하기 위한 스크립트 파일들의 모음과 어셈블리 참조들이 프로젝트에 추가됩니다.

    또는, 도구(Tools) | 라이브러리 패키지 관리자(Library Package Manager) | 패키지 관리자 콘솔(Package Manager Console) 메뉴를 선택해서 콘솔을 열고, 다음 명령을 실행해서 프로젝트에 SignalR을 추가할 수도 있습니다:

    install-Package Microsoft.AspNet.SignalR

    이렇게 콘솔을 통해서 SignalR을 추가한 경우에는, 별도로 SignalR 허브 클래스를 직접 생성해줘야 합니다.

    노트: Visual Studio 2012를 사용하고 있다면 SignalR 허브 클래스(v2)(SignalR Hub Class (v2)) 템플릿을 사용할 수 없을 것입니다. 대신 ChatHub라는 이름으로 일반적인 클래스를 추가하면 됩니다.

  4. 이제 솔루션 탐색기에서 Scripts 노트를 확장해봅니다. 그러면, 프로젝트에 jQuery와 SignalR을 위한 스크립트 라이브러리들이 추가된 것을 확인할 수 있습니다.

  5. 방금 생성한 ChatHub 클래스의 코드를 다음과 같이 변경합니다.

    using System;
    using System.Web;
    using Microsoft.AspNet.SignalR;
    
    namespace SignalRChat
    {
        public class ChatHub : Hub
        {
            public void Send(string name, string message)
            {
                // Call the broadcastMessage method to update clients.
                Clients.All.broadcastMessage(name, message);
            }
        }
    }
  6. 다시, 솔루션 탐색기에서 마우스 오른쪽 버튼으로 프로젝트를 클릭하고 추가(Add) | 새 항목(New Item) 메뉴를 선택해서 새 항목 추가(Add New Item) 대화 상자를 띄운 다음, 웹(Web) 카테고리에서 OWIN 시작 클래스(OWIN Startup Class)를 선택합니다. 클래스 이름을 Startup으로 지정한 다음, 추가(Add) 버튼을 클릭합니다.

    노트: Visual Studio 2012를 사용하고 있다면 OWIN 시작 클래스(OWIN Startup Class) 템플릿을 사용할 수 없을 것입니다. 대신 Startup라는 이름으로 일반적인 클래스를 추가하면 됩니다.

  7. 방금 생성한 Startup 클래스의 코드를 다음과 같이 변경합니다.

    using Microsoft.Owin;
    using Owin;
    
    [assembly: OwinStartup(typeof(SignalRChat.Startup))]
    namespace SignalRChat
    {
        public class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                // Any connection or hub wire up and configuration should go here
                app.MapSignalR();
            }
        }
    }
  8. 다시, 솔루션 탐색기에서 마우스 오른쪽 버튼으로 프로젝트를 클릭한 다음, 추가(Add) | HTML 페이지(HTML Page) 메뉴를 클릭합니다. 새 HTML 페이지의 이름은 index.html로 지정합니다.

  9. 그리고, 솔루션 탐색기에서 방금 생성한 HTML 페이지를 마우스 오른쪽 버튼으로 클릭한 다음, 시작 페이지로 설정(Set as Start Page) 메뉴를 클릭합니다.

  10. HTML 페이지의 기본 코드를 다음과 같이 변경합니다.

    노트: 만약, 패키지 관리자로 SignalR을 설치했다면 아마도 가장 최신 버전의 SignalR 스크립트들이 설치되었을 것입니다. 따라서, 프로젝트에 실제로 추가된 스크립트 파일들의 버전과 아래 코드에 작성된 스크립트 참조의 버전이 일치하는지 확인하시기 바랍니다. (허브 추가 방식 대신 NuGet으로 SignalR을 추가하면 파일들의 버전이 다를 가능성이 높습니다.) (역주: 그 이유는 NuGet 방식이 기본적으로 항상 해당 시점의 최신 버전을 설치하기 때문입니다. 가령, 2014년 1월 현재 가장 최신 버전은 2.0.1입니다.)

    <!DOCTYPE html>
    <html>
    <head>
        <title>SignalR Simple Chat</title>
        <style type="text/css">
            .container {
                background-color: #99CCFF;
                border: thick solid #808080;
                padding: 20px;
                margin: 20px;
            }
        </style>
    </head>
    <body>
        <div class="container">
            <input type="text" id="message" />
            <input type="button" id="sendmessage" value="Send" />
            <input type="hidden" id="displayname" />
            <ul id="discussion">
            </ul>
        </div>
        <!--Script references. -->
        <!--Reference the jQuery library. -->
        <script src="Scripts/jquery-1.10.2.min.js" ></script>
        <!--Reference the SignalR library. -->
        <script src="Scripts/jquery.signalR-2.0.0.min.js"></script>
        <!--Reference the autogenerated SignalR hub script. -->
        <script src="/signalr/hubs"></script>
        <!--Add script to update the page and send messages.-->
        <script type="text/javascript">
            $(function () {
                // Declare a proxy to reference the hub. 
                var chat = $.connection.chatHub;
                // Create a function that the hub can call to broadcast messages.
                chat.client.broadcastMessage = function (name, message) {
                    // Html encode display name and message. 
                    var encodedName = $('<div />').text(name).html();
                    var encodedMsg = $('<div />').text(message).html();
                    // Add the message to the page. 
                    $('#discussion').append('<li><strong>' + encodedName
                        + '</strong>:&nbsp;&nbsp;' + encodedMsg + '</li>');
                };
                // Get the user name and store it to prepend to messages.
                $('#displayname').val(prompt('Enter your name:', ''));
                // Set initial focus to message input box.  
                $('#message').focus();
                // Start the connection.
                $.connection.hub.start().done(function () {
                    $('#sendmessage').click(function () {
                        // Call the Send method on the hub. 
                        chat.server.send($('#displayname').val(), $('#message').val());
                        // Clear text box and reset focus for next comment. 
                        $('#message').val('').focus();
                    });
                });
            });
        </script>
    </body>
    </html>
  11. 변경된 프로젝트의 내용들을 모두 저장합니다.

샘플 실행하기

  1. F5를 눌러서 프로젝트를 디버그 모드로 실행합니다. 그러면, HTML 페이지가 브라우저 인스턴스에 로드되고 사용자 이름을 요구하는 프롬프트가 나타날 것입니다.

    Enter user name

  2. 사용자 이름을 입력합니다.

  3. 브라우저 주소 창의 URL을 복사한 다음, 다른 브라우저 인스턴스 두 개를 더 열어서 이 URL를 입력합니다. 그리고, 브라우저 인스턴스마다 중복되지 않는 이름을 입력합니다.

  4. 각각의 브라우저 인스턴스에서 코멘트를 입력하고 Send 버튼을 클릭해봅니다. 그러면, 입력된 코멘트들이 모든 브라우저 인스턴스에 출력될 것입니다.

    노트: 이 간단한 챗 응용 프로그램은 서버 쪽에서 따로 대화 컨텍스트(Discussion Context)를 관리하지 않습니다. 허브는 새로운 코멘트를 모든 현재 사용자들에게 브로드캐스트 합니다. 챗에 참여한 사용자들은 자신이 참여한 이후에 전송된 메시지들을 보게 될 것입니다.

    다음 화면 이미지는 세 개의 브라우저 인스턴스에서 실행되는 챗 응용 프로그램을 보여주는데, 한 브라우저 인스턴스에서 메시지를 전송하면 모든 인스턴스들이 갱신됩니다.

    Chat browsers

  5. 응용 프로그램이 실행되는 동안 솔루션 탐색기에서 스크립트 문서(Script Documents) 노드를 살펴보시기 바랍니다. 그러면, hubs라는 이름의 스크립트 파일을 확인할 수 있을 텐데, 이 파일은 런타임에 동적으로 생성되는 SignalR의 라이브러리입니다. 바로 이 파일이 jQuery 스크립트와 서버 측 코드 간의 커뮤니케이션을 관리해줍니다.

코드 분석

이 SignalR 챗 응용 프로그램은 두 가지 기본적인 SignalR 개발을 보여주고 있습니다. 즉, 서버 상의 핵심 조정 개체인 허브를 생성하는 방법과, 메시지를 주고 받기 위해서 SignalR jQuery 라이브러리를 사용하는 방법이 바로 그것입니다.

SignalR 허브

이 샘플 코드의 ChatHub 클래스는 Microsoft.AspNet.SignalR.Hub 클래스를 상속 받고 있습니다. 이런 식으로 SignalR 응용 프로그램을 작성할 때, Hub 클래스를 상속 받으면 매우 유용합니다. Hub 클래스를 상속 받은 허브 클래스에 필요한 public 메서드들을 구현해 놓으면, 웹 페이지에서 jQuery 스크립트를 이용해서 이 메서드들을 호출해서 접근할 수 있습니다.

가령, 이 샘플 챗 응용 프로그램의 코드에서는 클라이언트가 ChatHub.Send 메서드를 호출해서 새로운 메시지를 전송합니다. 그러면, 허브가 Clients.All.broadcastMessage를 호출해서 모든 클라이언트들에게 메시지를 전송합니다.

이 Send 메서드는 허브의 몇 가지 개념들을 보여줍니다:

  • 허브에 public 메서드를 선언해 놓으면 클라이언트에서 이 메서드들을 호출할 수 있습니다.
  • Microsoft.AspNet.SignalR.Hub.Clients 동적 속성을 사용하면 해당 허브에 접속되어 있는 모든 클라이언트에 접근할 수 있습니다.
  • 클라이언트 측의 jQuery 함수(broadcastMessage 함수 같은)를 호출해서 클라이언트를 업데이트 합니다.

    public class ChatHub : Hub
    {
        public void Send(string name, string message)
        {
            // Call the broadcastMessage method to update clients.
            Clients.All.broadcastMessage(name, message);
        }
    }

SignalR과 jQuery

코드 샘플의 HTML 페이지에서는 SignalR jQuery 라이브러리를 사용해서 SignalR 허브와 커뮤니케이션 하는 방법을 보여줍니다. 이 코드가 수행하는 핵심 작업은 허브를 참조하기 위한 프록시 변수 선언 작업과 서버에서 클라이언트로 콘텐트를 푸시할 때 호출할 함수를 선언하는 작업, 그리고 메시지를 허브로 전송하기 위해 연결을 시작하는 작업입니다.

다음은 허브 프록시에 대한 참조를 선언하는 코드입니다.

var chat = $.connection.chatHub; 

노트: 자바스크립트로 서버의 클래스와 그 메서드를 참조할 때는 카멜 표기법을 사용합니다. 즉, 자바스크립트에서는 chatHub를 참조하고 있지만, 이 코드가 실제로 참조하는 C# 클래스는 ChatHub입니다.

그리고, 다음 코드는 스크립트에서 콜백 함수를 생성하는 방법을 보여주고 있습니다. 서버 상의 허브 클래스는 이 함수를 호출해서 각각의 클라이언트에 갱신된 콘텐트를 푸시할 수 있습니다. 참고로, 이 코드에서 콘텐트를 출력하기 전에 HTML 인코드를 수행하는 두 라인의 코드는, 비록 필수적인 코드는 아니지만 간단하게 스크립트 인젝션을 방지할 수 있는 방법을 보여줍니다.

chat.client.broadcastMessage = function (name, message) {
    // Html encode display name and message. 
    var encodedName = $('<div />').text(name).html();
    var encodedMsg = $('<div />').text(message).html();
    // Add the message to the page. 
    $('#discussion').append('<li><strong>' + encodedName + '</strong>:&nbsp;&nbsp;' + encodedMsg + '</li>');
}; 

다음 코드는 허브 연결을 여는 방법을 보여줍니다. 이 코드는 먼저 연결을 시작한 다음, 이를 HTML 페이지의 Send 버튼의 click 이벤트를 처리하는 함수에 전달합니다.

노트: 이런 방법을 사용하면, 이벤트 처리기가 동작하기 전에 항상 연결이 먼저 이루어져 있는 것을 보장할 수 있습니다.

$.connection.hub.start().done(function () {
    $('#sendmessage').click(function () {
        // Call the Send method on the hub. 
        chat.server.send($('#displayname').val(), $('#message').val());
        // Clear text box and reset focus for next comment. 
        $('#message').val('').focus();
    });
});

이후 과정 안내

본문에서는 실시간 웹 응용 프로그램을 구축하기 위한 SignalR 프레임워크에 대해서 살펴봤습니다. ASP.NET 응용 프로그램에 SignalR을 추가하는 방법과 허브 클래스를 추가하는 방법, 그리고 허브를 이용해서 메시지를 전송하고 수신하는 방법 등 몇 가지 SignalR 개발 작업들을 살펴봤습니다.

본 자습서의 예제 응용 프로그램이나 다른 SignalR 응용 프로그램들을 호스팅 공급자에 배포해서 인터넷 상에서 사용할 수도 있습니다. 마이크로소프트는 최대 10개까지 웹 사이트를 무료로 호스팅 할 수 있는 Windows Azure trial account를 제공해주고 있습니다. 예제 SignalR 응용 프로그램을 배포하는 과정은 Publish the SignalR Getting Started Sample as a Windows Azure Web Site 포스트를 참고하시기 바랍니다. 그리고, Visual Studio 웹 프로젝트를 Windows Azure 웹 사이트에 배포하는 방법에 대한 더 자세한 정보는 Deploying an ASP.NET Application to a Windows Azure Web Site를 참고하시기 바랍니다.

노트: 현재 Windows Azure 웹 사이트에서는 WebSocket 전송방식이 지원되지 않습니다. WebSocket 전송방식을 사용할 수 없는 경우, SignalR은 ASP.NET SignalR 2.0: SignalR 소개 문서의 전송방식들(Transports)과 그 대안(Fallbacks) 절에서 설명한 것처럼 사용 가능한 다른 전송방식들을 사용하게 됩니다. *

더 고급의 SignalR 개발 개념들을 살펴보고 싶다면, SignalR 소스 코드와 리소스들이 제공되는 다음 사이트들을 방문해보시기 바랍니다:

* 이제 Windows Azure 웹 사이트에서도 .NET 프레임워크 버전이 4.5로 설정되어 있고, 사이트 구성 페이지의 웹 소켓 항목이 활성화되어 있으면 WebSocket을 사용할 수 있습니다