SignalR 소개
경고
이 설명서는 최신 버전의 SignalR용이 아닙니다. ASP.NET Core SignalR을 살펴보세요.
이 문서에서는 SignalR이란 무엇이며 생성하도록 디자인된 솔루션 중 일부에 대해 설명합니다.
질문 및 의견
이 자습서를 어떻게 좋아했는지, 그리고 페이지 하단의 주석에서 개선할 수 있는 사항에 대한 피드백을 남겨 주세요. 자습서와 직접 관련이 없는 질문이 있는 경우 ASP.NET SignalR 포럼 또는 StackOverflow.com 게시할 수 있습니다.
SignalR이란?
ASP.NET SignalR은 애플리케이션에 실시간 웹 기능을 추가하는 프로세스를 간소화하는 ASP.NET 개발자를 위한 라이브러리입니다. 실시간 웹 기능은 서버가 클라이언트가 새 데이터를 요청할 때까지 기다리지 않고 서버 코드가 연결된 클라이언트에 콘텐츠를 즉시 푸시하도록 하는 기능입니다.
SignalR은 모든 종류의 "실시간" 웹 기능을 ASP.NET 애플리케이션에 추가하는 데 사용할 수 있습니다. 채팅이 예로 사용되는 경우가 많지만 훨씬 더 많은 작업을 수행할 수 있습니다. 사용자가 새 데이터를 보기 위해 웹 페이지를 새로 고치거나 페이지가 새 데이터를 검색하기 위해 긴 폴링을 구현할 때마다 SignalR을 사용할 후보입니다. 예를 들어 대시보드 및 모니터링 애플리케이션, 공동 작업 애플리케이션(예: 문서 동시 편집), 작업 진행률 업데이트 및 실시간 양식이 있습니다.
또한 SignalR은 실시간 게임과 같이 서버에서 고주파 업데이트를 필요로 하는 완전히 새로운 유형의 웹 애플리케이션을 사용하도록 설정합니다.
SignalR은 서버 쪽 .NET 코드에서 클라이언트 브라우저(및 기타 클라이언트 플랫폼)에서 JavaScript 함수를 호출하는 RPC(서버 간 원격 프로시저 호출)를 만드는 간단한 API를 제공합니다. SignalR에는 연결 관리(instance, 연결 및 연결 끊기 이벤트) 및 연결 그룹화용 API도 포함되어 있습니다.
SignalR은 연결 관리를 자동으로 처리하며, 대화방처럼 메시지를 연결된 모든 클라이언트에 동시에 브로드캐스트할 수 있습니다. 메시지를 특정 클라이언트에 보낼 수도 있습니다. 클라이언트와 서버 간의 연결은 기존 HTTP 연결과 달리 영구적이며, 각 통신에 대해 다시 설정됩니다.
SignalR은 현재 웹에 공통된 요청 응답 모델 대신 RPC(원격 프로시저 호출)를 사용하여 브라우저에서 서버 코드가 클라이언트 코드로 호출할 수 있는 "서버 푸시" 기능을 지원합니다.
SignalR 애플리케이션은 기본 제공 및 타사 스케일 아웃 공급자를 사용하여 수천 개의 클라이언트로 확장할 수 있습니다.
기본 제공 공급자는 다음과 같습니다.
타사 공급자는 다음과 같습니다.
SignalR은 GitHub를 통해 액세스할 수 있는 오픈 소스입니다.
SignalR 및 WebSocket
SignalR은 사용 가능한 새 WebSocket 전송을 사용하고 필요한 경우 이전 전송으로 돌아갑니다. WebSocket을 사용하여 앱을 직접 작성할 수 있지만 SignalR을 사용하면 구현해야 하는 많은 추가 기능이 이미 완료되었음을 의미합니다. 가장 중요한 것은 이전 클라이언트에 대한 별도의 코드 경로를 만드는 것에 대해 걱정할 필요 없이 WebSocket을 활용하도록 앱을 코딩할 수 있다는 것입니다. 또한 SignalR은 기본 전송의 변경 내용을 지원하도록 업데이트되므로 WebSocket 업데이트에 대해 걱정할 필요가 없도록 보호하므로 WebSocket 버전 간에 애플리케이션에 일관된 인터페이스를 제공합니다.
전송 및 대체
SignalR은 클라이언트와 서버 간의 실시간 작업을 수행하는 데 필요한 일부 전송에 대한 추상화입니다. SignalR은 가능한 경우 먼저 WebSocket 연결을 설정하려고 시도합니다. WebSocket은 다음이 있기 때문에 SignalR에 가장 적합한 전송입니다.
- 서버 메모리를 가장 효율적으로 사용합니다.
- 가장 낮은 대기 시간입니다.
- 클라이언트와 서버 간의 전체 이중 통신과 같은 가장 기본 기능입니다.
- 가장 엄격한 요구 사항인 WebSocket에는 서버가 필요합니다.
- Windows Server 2012 또는 Windows 8에서 실행합니다.
- .NET Framework 4.5.
이러한 요구 사항이 충족되지 않으면 SignalR은 다른 전송을 사용하여 연결을 시도합니다.
HTML 5 전송
이러한 전송은 HTML 5에 대한 지원에 따라 달라집니다. 클라이언트 브라우저가 HTML 5 표준을 지원하지 않는 경우 이전 전송이 사용됩니다.
- WebSocket (서버와 브라우저 모두 Websocket을 지원할 수 있음을 나타내는 경우). WebSocket은 클라이언트와 서버 간에 진정한 영구 양방향 연결을 설정하는 유일한 전송입니다. 그러나 WebSocket에는 가장 엄격한 요구 사항도 있습니다. 최신 버전의 Microsoft Internet Explorer, Google Chrome 및 Mozilla Firefox에서만 완전히 지원되며 Opera 및 Safari와 같은 다른 브라우저에서만 부분 구현됩니다.
- EventSource라고도 하는 서버 전송 이벤트(브라우저에서 기본적으로 인터넷 Explorer 제외한 모든 브라우저인 서버 전송 이벤트를 지원하는 경우).
혜성 수송
다음 전송은 브라우저 또는 다른 클라이언트가 클라이언트가 특별히 요청하지 않고 클라이언트에 데이터를 푸시하는 데 사용할 수 있는 장기 HTTP 요청을 유지하는 Comet 웹 애플리케이션 모델을 기반으로 합니다.
- Forever Frame(인터넷 Explorer 전용). Forever Frame은 완료되지 않은 서버의 엔드포인트에 대한 요청을 만드는 숨겨진 IFrame을 만듭니다. 그런 다음 서버는 즉시 실행되는 클라이언트에 스크립트를 지속적으로 전송하여 서버에서 클라이언트로의 단방향 실시간 연결을 제공합니다. 클라이언트에서 서버로의 연결은 서버에서 클라이언트 연결로의 별도 연결을 사용하며, 표준 HTTP 요청과 마찬가지로 전송해야 하는 각 데이터에 대해 새 연결이 만들어집니다.
- Ajax 긴 폴링. 긴 폴링은 영구 연결을 만들지 않고 대신 서버가 응답할 때까지 열려 있는 요청으로 서버를 폴링합니다. 이때 연결이 닫히면 새 연결이 즉시 요청됩니다. 이렇게 하면 연결이 다시 설정되는 동안 약간의 대기 시간이 발생할 수 있습니다.
어떤 전송이 어떤 구성에서 지원되는지에 대한 자세한 내용은 지원되는 플랫폼을 참조하세요.
전송 선택 프로세스
다음 목록에서는 SignalR이 사용할 전송을 결정하는 데 사용하는 단계를 보여줍니다.
브라우저가 인터넷 Explorer 8 이전 버전인 경우 긴 폴링이 사용됩니다.
JSONP가 구성된 경우(즉,
jsonp
연결이 시작될 때 매개 변수가 로true
설정됨) Long 폴링이 사용됩니다.도메인 간 연결이 이루어지는 경우(즉, SignalR 엔드포인트가 호스팅 페이지와 동일한 도메인에 없는 경우) 다음 조건이 충족되면 WebSocket이 사용됩니다.
클라이언트는 CORS(원본 간 리소스 공유)를 지원합니다. CORS를 지원하는 클라이언트에 대한 자세한 내용은 caniuse.com CORS를 참조하세요.
클라이언트가 WebSocket을 지원합니다.
서버에서 WebSocket을 지원합니다.
이러한 조건이 충족되지 않으면 긴 폴링이 사용됩니다. 도메인 간 연결에 대한 자세한 내용은 도메인 간 연결을 설정하는 방법을 참조하세요.
JSONP가 구성되지 않고 연결이 도메인 간이 아닌 경우 클라이언트와 서버가 모두 지원하는 경우 WebSocket이 사용됩니다.
클라이언트 또는 서버에서 WebSocket을 지원하지 않는 경우 서버 전송 이벤트를 사용할 수 있는 경우 사용됩니다.
서버 전송 이벤트를 사용할 수 없는 경우 Forever Frame이 시도됩니다.
Forever Frame이 실패하면 긴 폴링이 사용됩니다.
전송 모니터링
허브에서 로깅을 사용하도록 설정하고 브라우저에서 콘솔 창을 열어 애플리케이션이 사용 중인 전송을 확인할 수 있습니다.
브라우저에서 허브 이벤트에 대한 로깅을 사용하도록 설정하려면 클라이언트 애플리케이션에 다음 명령을 추가합니다.
$.connection.hub.logging = true;
인터넷 Explorer F12를 눌러 개발자 도구를 열고 콘솔 탭을 클릭합니다.
Chrome에서 Ctrl+Shift+J를 눌러 콘솔을 엽니다.
콘솔을 열고 로깅을 사용하도록 설정하면 SignalR에서 사용 중인 전송을 확인할 수 있습니다.
전송 지정
전송 협상은 일정 시간 및 클라이언트/서버 리소스가 필요합니다. 클라이언트 기능이 알려진 경우 클라이언트 연결이 시작될 때 전송을 지정할 수 있습니다. 다음 코드 조각은 클라이언트가 다른 프로토콜을 지원하지 않는 것으로 알려진 경우와 마찬가지로 Ajax Long Polling 전송을 사용하여 연결을 시작하는 방법을 보여 줍니다.
connection.start({ transport: 'longPolling' });
클라이언트가 특정 전송을 순서대로 시도하도록 하려면 대체 순서를 지정할 수 있습니다. 다음 코드 조각은 WebSocket을 시도하고 실패하여 Long 폴링으로 직접 가는 방법을 보여 줍니다.
connection.start({ transport: ['webSockets','longPolling'] });
전송을 지정하기 위한 문자열 상수는 다음과 같이 정의됩니다.
webSockets
foreverFrame
serverSentEvents
longPolling
연결 및 허브
SignalR API에는 클라이언트와 서버 간의 통신을 위한 두 가지 모델인 영구 연결 및 허브가 포함되어 있습니다.
연결은 단일 수신자, 그룹화 또는 브로드캐스트 메시지를 보내기 위한 간단한 엔드포인트를 나타냅니다. Persistent Connection API(PersistentConnection 클래스에서 .NET 코드로 표시됨)는 개발자에게 SignalR이 노출하는 하위 수준 통신 프로토콜에 직접 액세스할 수 있도록 합니다. 연결 통신 모델을 사용하면 Windows Communication Foundation과 같은 연결 기반 API를 사용한 개발자에게 익숙할 것입니다.
허브는 클라이언트와 서버가 서로 메서드를 직접 호출할 수 있도록 하는 연결 API를 기반으로 구축된 보다 높은 수준의 파이프라인입니다. SignalR은 마치 매직을 통해 컴퓨터 경계를 넘어 디스패치를 처리하므로 클라이언트는 로컬 메서드처럼 서버에서 메서드를 쉽게 호출할 수 있고 그 반대의 경우도 마찬가지입니다. 허브 통신 모델을 사용하면 .NET Remoting과 같은 원격 호출 API를 사용한 개발자에게 익숙할 것입니다. 허브를 사용하면 강력한 형식의 매개 변수를 메서드에 전달하여 모델 바인딩을 사용하도록 설정할 수도 있습니다.
아키텍처 다이어그램
다음 다이어그램은 허브, 영구 연결 및 전송에 사용되는 기본 기술 간의 관계를 보여 줍니다.
허브 작동 방식
서버 쪽 코드가 클라이언트에서 메서드를 호출하면 호출할 메서드의 이름과 매개 변수가 포함된 활성 전송 간에 패킷이 전송됩니다(개체가 메서드 매개 변수로 전송되면 JSON을 사용하여 직렬화됨). 그런 다음 클라이언트는 메서드 이름을 클라이언트 쪽 코드에 정의된 메서드와 일치합니다. 일치하는 항목이 있으면 역직렬화된 매개 변수 데이터를 사용하여 클라이언트 메서드가 실행됩니다.
Fiddler와 같은 도구를 사용하여 메서드 호출을 모니터링할 수 있습니다. 다음 이미지는 Fiddler의 로그 창에서 SignalR 서버에서 웹 브라우저 클라이언트로 전송된 메서드 호출을 보여 줍니다. 메서드 호출이 라는 MoveShapeHub
허브에서 전송되고 호출되는 메서드를 라고 합니다 updateShape
.
이 예제에서 허브 이름은 매개 변수로 H
식별되고, 메서드 이름은 매개 변수로 M
식별되고, 메서드로 전송되는 데이터는 매개 변수로 A
식별됩니다. 이 메시지를 생성한 애플리케이션은 고주파 실시간 자습서에서 만들어집니다.
통신 모델 선택
대부분의 애플리케이션은 Hubs API를 사용해야 합니다. 연결 API는 다음과 같은 경우에 사용할 수 있습니다.
- 전송된 실제 메시지의 형식을 지정해야 합니다.
- 개발자는 원격 호출 모델보다는 메시징 및 디스패치 모델을 사용하는 것을 선호합니다.
- 메시징 모델을 사용하는 기존 애플리케이션이 SignalR을 사용하도록 포팅되고 있습니다.