내용으로 건너뛰기
SignalR을 사용하여 실시간 앱 빌드 – 2부

SignalR을 사용하여 실시간 앱 빌드 – 2부

이 게시물은 SignalR의 요구 사항, 기본 사항, 구성 및 전송 메커니즘에 대해 논의한 이전 게시물의 연속입니다. 이 게시물에서는 샘플 애플리케이션을 만들고 추가로 분석하여 한 단계 더 나아갈 것입니다.

7min read

이 게시물은 SignalR의 요구 사항, 기본 사항, 구성 및 전송 메커니즘에 대해 논의한 이전 게시물의 연속입니다. 이 게시물에서는 샘플 애플리케이션을 만들고 추가로 분석하여 한 단계 더 나아갈 것입니다.

대체로 이 게시물은 두 가지 주요 부분으로 나눌 수 있습니다.첫 번째 부분에서는 샘플을 만들고 다른 부분에서는 SignalR이 다양한 환경에서 어떻게 작동하는지 확인하고 클라이언트와 서버 간의 통신 요청을 살펴보겠습니다.

샘플 작업

서버 모니터링은 다양한 시나리오에서 여러 번 수행하는 중요한 작업 중 하나입니다. 이를 수행하는 한 가지 간단한 방법은 모니터링할 서버에 원격 로그인하는 것입니다 – 또는 서버를 연결하고 필요한 성능 카운터를 추출하여 그에 따라 해당 정보를 표시하는 클라이언트를 사용할 수도 있습니다.

이 예에서는 서버 리소스 사용률을 실시간으로 보여주는 서버 모니터링 응용 프로그램을 만들 것입니다. 우리의 목표는 SignalR을 설명하는 것이기 때문에 샘플은 기본 샘플이 될 것이며 서버의 몇 가지 기본 카운터를 읽고 해당 정보를 UI에 표시할 것입니다. UI는 매초마다 업데이트되며, 이는 매초마다 클라이언트에 데이터를 푸시하는 서버의 타이머를 통해 구현됩니다.

이전 게시물에서 필요한 구성을 이미 확인했으므로 빈 ASP.NET 애플리케이션을 만들고 다음 단계를 완료했습니다.

  • 설치된 SignalR Nuget 패키지
  • Startup 클래스 추가 및 Configuration 메소드 추가
  • HTML 파일을 Index.HTML으로 추가하고 jQuery, jQuery SignalR 및 Hub 프록시를 추가했습니다.

모든 SignalR 애플리케이션의 핵심 부분은 HUB입니다. 여기서 우리가 할 두 가지 주요 작업이 있습니다. 첫 번째는 서버 리소스 카운터를 읽는 것이고, 두 번째는 특정 간격(이 예에서는 1초) 후에 이 정보를 연결된 클라이언트로 푸시하는 것입니다. 이제 허브 구현을 살펴보겠습니다.

[HubMethodName("sendSeverDetails")]
public void SendSeverDetails()
{
	string processorTime;
	string memoryUsage;
	string diskReadperSec;
	string diskWriteperSec;
	string diskTransferperSec;

	// Getting the server counters
	GetServerUsageDetails(out processorTime, out memoryUsage, out
		diskReadperSec, out diskWriteperSec, out diskTransferperSec);

	// Broadcasting the counters to the connected clients
	Clients.All.SendSeverDetails(processorTime, memoryUsage,
		diskReadperSec, diskWriteperSec, diskTransferperSec, DateTime.Now.ToString());
}

이것이 핵심 허브 방법입니다. 여기서 우리는 서버의 카운터를 가져온 다음 클라이언트 콜백 함수를 호출하고 모든 매개변수를 전달합니다. 이 예에서는 각 카운터 값에 대해 다른 매개변수를 전달하지만 인스턴스를 만들고 JSON 문자열을 전달할 수도 있습니다. 최신 카운터로 클라이언트를 계속 업데이트해야 하므로 특정 간격(여기서는 1초라고 가정)으로 이 메서드를 호출해야 합니다. 이것은 다음과 같이 타이머를 통해 달성할 수 있습니다.

static Timer myTimer;

private readonly TimeSpan _updateInterval = TimeSpan.FromMilliseconds(1000);

public ServerDetailsHub()
{
	myTimer = new System.Threading.Timer(UpdateUI, null, _updateInterval, _updateInterval); 
	// Rest of the code removed for brevity. Download the solution for complete code
}

// This is called via Timer after certain interval which inturn calls the core hub method
private void UpdateUI(object state)
{
	SendSeverDetails();
}

이제 콜백 메소드를 정의한 클라이언트 측을 살펴보겠습니다.

$(function () {
    var num = 1;
    // Declare a proxy to reference the hub.
    var hubProxy = $.connection.serverDetailsHub;
    // Create a function that the hub can call to broadcast messages.
    hubProxy.client.sendSeverDetails = function (processorTime, memoryUsage, diskReadperSec, diskWriteperSec, diskTransferperSec, when) {
        $('#tblServerUsage tr').last().after("<tr><td>" + num++ + "</td><td>" + processorTime + "</td><td>" + memoryUsage + "</td><td>"
            + diskReadperSec + "</td><td>" + diskWriteperSec + "</td><td>" + diskTransferperSec + "</td><td>" + when + "</td></tr>");               
    };
 
    // Start the connection.
    $.connection.hub.start();
});

참고 – 이 예제에 대한 전체 코드는 여기에서 다운로드할 수 있습니다.

위의 코드에는 우리가 하고 있는 세 가지 작업이 있습니다. 먼저 허브 프록시를 만듭니다. 둘째, 서버에서 호출되고 동일한 수의 매개변수를 사용하는 콜백 메서드를 정의했습니다. 그리고 세 번째는, 또 다른 매우 중요한 단계로, 허브를 시작하는 것입니다. 이러한 단계는 서버와의 협상을 수행하고 서버와의 영구 연결을 만듭니다. 이 데모에서는 서버에서 새 데이터를받을 때마다 새 행을 추가합니다.

응용 프로그램 분석

SignalR은 런타임에 프록시 인스턴스를 만들고 서버에서 연결을 설정하는 데 사용되는 프록시 JavaScript를 만듭니다. 다음과 같이 프록시 URL을 탐색하면 확인할 수 있습니다.

다음과 같이 프록시 URL을 탐색하면 볼 수 있습니다

이전 게시물에서 SignalR은 여러 전송 메커니즘을 사용할 수 있으며 시나리오에 따라 최상의 옵션 중 하나를 선택한다고 설명했습니다. 따라서 협상을 선택하기 전에 협상이 어떻게 이루어지는지 살펴보겠습니다.

따라서 협상을 선택하기 전에 협상이 어떻게 이루어지는지 살펴보겠습니다.

위의 트래픽은 IE 11에서 샘플을 실행하는 동안 캡처됩니다. 필요한 스크립트를 다운로드한 후 허브(위에서 논의한 프록시)를 다운로드합니다. 그러면 협상 요청을 서버로 보내는 빨간색 원으로 둘러싸인 영역이 표시됩니다. 이를 기반으로 다음 요청에서 webSockets 전송이 선택됩니다. 클라이언트마다 고유한 연결 토큰과 같은 요청과 함께 몇 가지 다른 데이터도 있습니다.

다른 환경에서 동일한 응용 프로그램을 관찰해 보겠습니다.

이러한 세부 정보는 Chrome에서 캡처되었으며, 여기서는 일반적인 요청과 별도로 협상 요청을 보내고 serverSentEevents를 전송으로 선택하고 선택한 전송을 사용하여 요청을 시작하는 것을 볼 수 있습니다. 시나리오를 하나 더 살펴보겠습니다.

IE9를 통해 선택한 전송이 연결을 시작하는 foreverFrame 이라는 점을 제외하고는 위와 유사한 세 가지 요청을 받았습니다.

협상 요청에 따라 SignalR은 최상의 옵션 중 하나를 선택하고 웹 소켓을 제외하고 연결을 시작하려면 한 번 더 요청이 필요합니다.

전송 프로토콜 제한

SignalR은 매우 유연하며 필요에 따라 다양한 구성 옵션을 허용합니다. 특정 전송으로 구성하거나 특정 순서로 대체를 제공할 수도 있습니다. 또한 SignalR이 사용할 전송 프로토콜을 이미 알고 있으므로 연결을 시작하는 초기 시간 프레임을 줄이는 데 도움이 됩니다. 허브를 시작하는 동안 특정 전송을 제공할 수 있는 이유는 프로토콜 선택을 결정하는 기능이기 때문입니다.

$.connection.hub.start({ transport: 'foreverFrame' });

우리는 또한 다음과 같이 대체 옵션을 제공합니다.

$.connection.hub.start({ transport: ['foreverFrame', 'longPolling'] });

참고 –$.connection.hub.start()와 유사하게 프록시는 $.connection.hub.stop()과 같이 영구 연결을 중지하는 또 다른 기능을 제공하며 일단 호출되면 클라이언트와 서버 간의 통신을 계속하기 위해 허브를 다시 시작해야 합니다.

결론

이 게시물에서는 서버가 연결된 모든 클라이언트에 특정 간격으로 서버 사용 카운터 세부 정보를 푸시하는 서버 모니터 샘플을 만들었습니다. 우리는 특정 간격 후에 이벤트를 발생시키는 타이머를 사용했으며, 이 이벤트는 먼저 카운터를 수집하고 연결된 클라이언트로 브로드캐스트합니다.

또한 다양한 시나리오에서 사용되는 다양한 전송 프로토콜을 검사하기 위해 개발자 도구를 살펴보았고 동일한 애플리케이션이 협상에 따라 다른 프로토콜을 사용하는 것을 확인했습니다. 또한 전송 범위를 좁히거나 특정 프로토콜을 제공하여 초기 오버헤드를 줄이는 방법도 확인했습니다.

이 게시물이 즐거웠기를 바라며 읽어 주셔서 감사합니다!

데모 요청