자습서: SignalR 시작하기 (C#)

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

SignalR 소개

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

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

본 자습서에서는 간단한 브라우저 기반 챗 응용 프로그램 구축 방법을 살펴보면서 SignalR 개발을 소개하고자 합니다. 다음과 같은 개발자 작업을 수행해볼 것입니다:

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

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

Chat instances

노트: 본문은 SignalR 1.x 버전에 대해서 설명하고 있는 문서입니다. 그러나 2013년 12월 현재 이미 SignalR 2.0 버전이 릴리즈 된 상태므로 이 점 참고하시기 바랍니다.

목차:

프로젝트 설정하기

이번 절에서는 새로운 ASP.NET 웹 응용 프로그램을 생성하고, SignalR 라이브러리를 추가하고, 챗 응용 프로그램을 작성하는 방법을 살펴보겠습니다. Visual Studio 2010 SP1 또는 2012와 .NET 프레임워크 4.0 또는 4.5를 사용합니다. 본문에서는 Visual Studio 2012와 ASP.NET 4.5를 사용하겠습니다.

  1. Visual Studio에서 ASP.NET 빈 웹 응용 프로그램(ASP.NET Empty Web Application)을 생성합니다.

    Create empty web

  2. 도구(Tools) | 라이브러리 패키지 관리자(Library Package Manager) | 패키지 관리자 콘솔(Package Manager Console) 메뉴를 열고 프롬프트에 다음의 명령을 입력합니다.

    install-package Microsoft.AspNet.SignalR -pre
  3. 그런 다음, 솔루션 탐색기에서 프로젝트의 참조(References) 노드와 Scripts 노드를 펼쳐봅니다. 참조 노드에는 SignalR ASP.NET 라이브러리에 대한 참조가 추가되어 있을 것입니다. 그리고, Scripts 노드에는 jQuery 및 SignalR jQuery 라이브러리가 추가되어 있을 것입니다.

    Library references

  4. 솔루션 탐색기에서 프로젝트를 마우스 오른쪽 버튼으로 클릭한 다음, 추가(Add) | 새 항목(New Item)을 클릭합니다. 새 항목 추가(Add New Item) 대화 상자가 나타나면, 전역 응용 프로그램 클래스(Global Application Class)를 선택하고 추가(Add) 버튼을 클릭합니다.

    Add global

  5. 다음 using 구문을 Global.asax.cs 클래스에서 기존에 제공되던 using 구문 뒤에 추가합니다.

    using System.Web.Routing;
    using Microsoft.AspNet.SignalR;
  6. 다음 코드 라인을 Global 클래스의 Application_Start 메서드에 추가해서 SignalR 허브에 대한 기본 라우트를 등록합니다.

    // Register the default hubs route: ~/signalr/hubs
    RouteTable.Routes.MapHubs();
  7. 솔루션 탐색기에서 프로젝트를 마우스 오른쪽 버튼으로 클릭한 다음, 추가(Add) | 클래스(Class)를 클릭합니다. 클래스의 이름으로 ChatHub.cs를 지정하고 추가(Add) 버튼을 클릭합니다.

  8. 자동으로 생성된 기본 클래스 코드를 다음 코드로 교체합니다.

    using System;
    using System.Web;
    using Microsoft.AspNet.SignalR;
    
    public class ChatHub : Hub
    {
        public void Send(string name, string message)
        {
            // Call the broadcastMessage method to update clients.
            Clients.All.broadcastMessage(name, message);
        }
    }
    
  9. 솔루션 탐색기에서 프로젝트를 마우스 오른쪽 버튼으로 클릭한 다음, 추가(Add) | 새 항목(New Item)을 클릭합니다. 새 항목 추가(Add New Item) 대화 상자가 나타나면, Html 페이지(Html Page)를 선택하고 추가(Add) 버튼을 클릭합니다.

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

  11. 자동으로 생성된 HTML 페이지의 기본 코드를 다음 코드로 교체합니다.

    <!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.6.4.min.js" ></script>
        <!--Reference the SignalR library. -->
        <script src="Scripts/jquery.signalR-1.0.0-rc2.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>
  12. 프로젝트의 변경된 내용들을 모두 저장합니다.

샘플 실행하기

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

    역주: 저의 경우, ASP.NET 개발 서버를 사용하면 잘 실행되고 IIS Express를 사용하면 실행이 잘 안됐습니다. 아마도 추가적인 설정이 필요한 것으로 보입니다.

    Enter user name

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

  3. 코멘트를 입력한 다음, Send 버튼을 클릭해봅니다.
  4. 응용 프로그램이 실행되는 동안, 솔루션 탐색기에서 스크립트 문서(Script Documents) 노드를 살펴봅니다. 그러면, hubs라는 이름의 스크립트 파일을 볼 수 있을텐데, 이는 런타임에 동적으로 생성되는 SignalR 라이브러리 입니다. 이 파일이 jQuery 스크립트와 서버 측 코드 간의 커뮤니케이션을 관리해줍니다.

    Generated hub script

  5. 브라우저에서 주소 창의 URL을 복사한 다음, 다른 브라우저 인스턴스를 열어서 이 URL를 입력합니다.

  6. 다른 사용자 이름을 입력한 다음, 각각의 인스턴스에서 코멘트를 추가로 입력해 봅니다.

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

    다음 화면 이미지들은 세 가지 별도 브라우저 인스턴스들에서 실행되는 챗 응용 프로그램을 보여줍니다. 각각의 사용자들은 자신이 참여한 이후에 전송된 메시지들을 보고 있습니다.

    Chat browsers

코드 분석

이 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; 
노트: jQuery에서 서버의 클래스와 그 메서드를 참조할 때는 카멜 표기법을 사용합니다. 즉, jQuery에서는 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 개발 개념들을 살펴보고 싶다면, SignalR 소스 코드와 리소스들이 제공되는 다음의 사이트들을 방문해보시기 바랍니다: