다음을 통해 공유


Azure SignalR Management SDK 사용

Azure SignalR Management SDK를 사용하면 브로드캐스트 메시지처럼 직접 Azure SignalR Service를 통해 SignalR 클라이언트를 관리할 수 있습니다. 따라서 이 SDK는 서버리스 환경에서 사용할 수 있지만 이 환경으로 국한되지는 않습니다. 이 SDK를 사용하여 콘솔 앱, Azure 함수 또는 웹 서버 등의 모든 환경에서 Azure SignalR Service에 연결된 SignalR 클라이언트를 관리할 수 있습니다.

참고 항목

SDK 버전 1.9.x 및 이전 버전에 대한 가이드를 보려면 Azure SignalR Service 관리 SDK(레거시)로 이동합니다. 마이그레이션 지침을 읽을 수도 있습니다.

Important

원시 연결 문자열 데모용으로만 이 문서에 표시됩니다.

연결 문자열에는 애플리케이션이 Azure Web PubSub 서비스에 액세스하는 데 필요한 권한 부여 정보가 포함됩니다. 연결 문자열 내의 액세스 키는 서비스의 루트 암호와 비슷합니다. 프로덕션 환경에서는 항상 액세스 키를 보호합니다. Azure Key Vault를 사용하여 키를 안전하게 관리 및 회전하고 Microsoft Entra ID를 사용하여 연결 문자열 보호합니다.

액세스 키를 다른 사용자에게 배포하거나 하드 코딩하거나 다른 사용자가 액세스할 수 있는 일반 텍스트로 저장하지 않도록 합니다. 키가 손상되었다고 생각되면 키를 교체하세요.

기능

기능 Transient Persistent
브로드캐스트 ✔️ ✔️
일부 클라이언트를 제외한 브로드캐스트 ✔️ ✔️
클라이언트로 보내기 ✔️ ✔️
클라이언트로 보내기 ✔️ ✔️
사용자에게 보내기 ✔️ ✔️
사용자에게 보내기 ✔️ ✔️
그룹으로 보내기 ✔️ ✔️
그룹으로 보내기 ✔️ ✔️
일부 클라이언트를 제외하고 그룹으로 보내기 ✔️ ✔️
그룹에 사용자 추가 ✔️ ✔️
그룹에서 사용자 제거 ✔️ ✔️
그룹의 사용자인지 확인 ✔️ ✔️
여러 SignalR Service 인스턴스 지원 ✔️
MessagePack 클라이언트 지원 v1.21.0 이후 v1.20.0 이후
일시적 오류 발생 시 다시 시도 v1.22.0 이후

기능은 새 API와 함께 제공됩니다.

기능 Transient Persistent
연결이 있는지 확인 ✔️ v1.11 이후
그룹이 있는지 확인 ✔️ v1.11 이후
사용자가 있는지 확인 ✔️ v1.11 이후
클라이언트 연결 닫기 ✔️ v1.11 이후
  • 다양한 모드에 대한 자세한 내용은 여기에서 확인할 수 있습니다.

  • 관리 SDK에 대한 전체 샘플은 여기에서 찾을 수 있습니다.

사용

이 섹션에서는 관리 SDK를 사용하는 방법을 보여 줍니다.

Service Manager 만들기

에서 인스턴스 ServiceManager 를 빌드합니다 ServiceManagerBuilder.

원시 연결 문자열 데모용으로만 이 문서에 표시됩니다. 프로덕션 환경에서는 항상 액세스 키를 보호합니다. Azure Key Vault를 사용하여 키를 안전하게 관리 및 회전하고 Microsoft Entra ID를 사용하여 연결 문자열 보호합니다.


var serviceManager = new ServiceManagerBuilder()
                    .WithOptions(option =>
                    {
                        option.ConnectionString = "<Your Azure SignalR Service Connection String>";
                    })
                    .WithLoggerFactory(loggerFactory)
                    .BuildServiceManager();

ServiceManager를 사용하여 Azure SignalR 엔드포인트 상태를 확인하고 서비스 허브 컨텍스트를 만들 수 있습니다. 다음 섹션에서는 서비스 허브 컨텍스트를 만드는 방법에 대한 세부 정보를 제공합니다.

Azure SignalR 엔드포인트 상태를 확인하려면 ServiceManager.IsServiceHealthy 메서드를 사용할 수 있습니다. 여러 Azure SignalR 엔드포인트가 있는 경우 첫 번째 엔드포인트만 확인됩니다.

var health = await serviceManager.IsServiceHealthy(cancellationToken);

서비스 허브 컨텍스트 만들기

ServiceManager에서 ServiceHubContext의 인스턴스를 만듭니다.

var serviceHubContext = await serviceManager.CreateHubContextAsync("<Your Hub Name>",cancellationToken);

협상

기본 모드에서 엔드포인트 /<Your Hub Name>/negotiate은 Azure SignalR Service SDK의 협상을 위해 노출됩니다. SignalR 클라이언트는 이 엔드포인트에 도달한 다음, 나중에 Azure SignalR Service로 리디렉션됩니다.

서버리스 모드에서는 SignalR 클라이언트의 협상 요청을 처리하고 클라이언트를 Azure SignalR Service로 리디렉션하기 위해 협상 엔드포인트를 호스트하는 것이 좋습니다.

SignalR의 협상 프로토콜에서 리디렉션에 대한 자세한 내용을 읽어보세요.

엔드포인트 및 액세스 토큰은 SignalR 클라이언트를 Azure SignalR Service로 리디렉션하려는 경우에 유용합니다.

ServiceHubContext의 인스턴스를 사용하여 SignalR 클라이언트에서 Azure SignalR Service에 연결하기 위한 엔드포인트 URL 및 해당 액세스 토큰을 생성할 수 있습니다.

var negotiationResponse = await serviceHubContext.NegotiateAsync(new (){UserId = "<Your User Id>"});

허브 엔드포인트가 http://<Your Host Name>/<Your Hub Name>이고 협상 엔드포인트가 http://<Your Host Name>/<Your Hub Name>/negotiate이라고 가정해 보세요. 협상 엔드포인트를 호스트한 후에는 SignalR 클라이언트를 사용하여 다음과 같이 허브에 연결할 수 있습니다.

var connection = new HubConnectionBuilder().WithUrl("http://<Your Host Name>/<Your Hub Name>").Build();
await connection.StartAsync();

관리 SDK를 사용하여 SignalR 클라이언트를 Azure SignalR Service로 리디렉션하는 방법에 대한 샘플은 여기에서 찾을 수 있습니다.

메시지 보내기 및 그룹 관리

ServiceHubContextBuilder에서 빌드한 ServiceHubContext는 클래스는 IServiceHubContext를 구현하고 확장하는 클래스입니다. 클라이언트에 메시지를 보내고 그룹을 관리하는 데 사용할 수 있습니다.

try
{
    // Broadcast
    await hubContext.Clients.All.SendAsync(callbackName, obj1, obj2, ...);

    // Send to user
    await hubContext.Clients.User(userId).SendAsync(callbackName, obj1, obj2, ...);

    // Send to group
    await hubContext.Clients.Group(groupId).SendAsync(callbackName, obj1, obj2, ...);

    // add user to group
    await hubContext.UserGroups.AddToGroupAsync(userId, groupName);

    // remove user from group
    await hubContext.UserGroups.RemoveFromGroupAsync(userId, groupName);
}
finally
{
    await hubContext.DisposeAsync();
}

강력한 형식의 허브

강력한 형식의 허브는 클라이언트 메서드를 인터페이스로 추출할 수 있는 프로그래밍 모델로, 메서드 이름을 잘못 입력하거나 잘못된 매개 변수 형식을 전달하는 등의 오류를 방지합니다.

두 개의 문자열 매개 변수를 사용하는 ReceivedMessage라는 클라이언트 메서드가 있다고 가정해 보겠습니다. 강력한 형식의 허브가 없으면 hubContext.Clients.All.SendAsync("ReceivedMessage", user, message)를 통해 클라이언트로 브로드캐스트합니다. 강력한 형식의 허브가 있으면 먼저 다음과 같은 인터페이스를 정의합니다.

public interface IChatClient
{
    Task ReceiveMessage(string user, string message);
}

그런 다음, IHubContext<Hub<T>, T>를 구현하는 강력한 형식의 허브 컨텍스트를 만듭니다. T는 클라이언트 메서드 인터페이스입니다.

ServiceHubContext<IChatClient> serviceHubContext = await serviceManager.CreateHubContextAsync<IChatClient>(hubName, cancellationToken);

마지막으로 다음과 같이 메서드를 직접 호출할 수 있습니다.

await Clients.All.ReceiveMessage(user, message);

메시지 보내기의 차이점을 제외하고 ServiceHubContext와 같이 ServiceHubContext<T>를 사용하여 그룹을 협상하거나 관리할 수 있습니다.

여기의 ASP.NET Core 설명서에서 강력한 형식의 허브에 대해 자세히 읽어보세요.

전송 방식

이 SDK는 다음 두 가지 전송 형식으로 Azure SignalR Service와 통신할 수 있습니다.

  • 임시: 전송된 각 메시지에 대해 Http 요청 Azure SignalR Service를 만듭니다. 이 SDK는 단순히 임시 모드에서 Azure SignalR Service REST API를 래핑합니다. WebSockets 연결을 설정할 수 없는 경우에 유용합니다.
  • 영구: 먼저 WebSockets 연결을 만든 다음, 이 연결에서 모든 메시지를 보냅니다. 많은 수의 메시지를 보낼 때 유용합니다.

메시지의 인수 serialization 동작 요약

직렬화 Transient Persistent
기본 JSON 라이브러리 Newtonsoft.Json ASP.NET Core SignalR과 동일합니다.
Newtonsoft.Json: .NET Standard 2.0
System.Text.Json: .NET Core App 3.1 이상
MessagePack 클라이언트 지원 v1.21.0 이후 v1.20.0 이후

JSON 직렬화

관리 SDK에서 클라이언트로 전송된 메서드 인수는 JSON으로 직렬화됩니다. JSON serialization을 사용자 지정하는 방법에는 여러 가지가 있습니다. 가장 권장되는 것부터 차례대로 모든 방법을 설명합니다.

ServiceManagerOptions.UseJsonObjectSerializer(ObjectSerializer objectSerializer)

가장 권장되는 방법은 일반적인 추상 클래스 ObjectSerializer를 사용하는 것입니다. 이러한 클래스는System.Text.JsonNewtonsoft.Json과 같은 JSON serialization 라이브러리를 지원하고 모든 전송 형식에 적용하기 때문입니다. 일반적으로 편리한 JSON 구현 System.Text.JsonNewtonsoft.Json이 이미 제공되므로 ObjectSerializer를 직접 구현할 필요가 없습니다.

  • System.Text.Json을 JSON 처리 라이브러리로 사용하는 경우 기본 제공 JsonObjectSerializer는 serialization/deserialization에 System.Text.Json.JsonSerializer를 사용합니다. 다음은 JSON serialization에 카멜 대/소문자 이름을 사용하는 샘플입니다.

    var serviceManager = new ServiceManagerBuilder()
        .WithOptions(o =>
        {
            o.ConnectionString = "***";
            o.UseJsonObjectSerializer(new JsonObjectSerializer(new JsonSerializerOptions
            {
                PropertyNamingPolicy = JsonNamingPolicy.CamelCase
            }));
        })
        .BuildServiceManager();
    
    
  • Newtonsoft.Json을 JSON 처리 라이브러리로 사용하는 경우 먼저 .NET CLI를 사용하여 NuGet에서 패키지 Microsoft.Azure.Core.NewtonsoftJson을 설치합니다.

    dotnet add package Microsoft.Azure.Core.NewtonsoftJson
    

    다음은 NewtonsoftJsonObjectSerializer에서 카멜 대/소문자 이름을 사용하는 샘플입니다.

    var serviceManager = new ServiceManagerBuilder()
        .WithOptions(o =>
        {
            o.ConnectionString = "***";
            o.UseJsonObjectSerializer(new NewtonsoftJsonObjectSerializer(new JsonSerializerSettings()
            {
                ContractResolver = new CamelCasePropertyNamesContractResolver()
            }));
        })
        .BuildServiceManager();
    
  • 다른 JSON 처리 라이브러리를 사용하는 경우

    ObjectSerializer를 직접 구현할 수도 있습니다. 다음 링크가 도움이 될 수 있습니다.

ServiceManagerBuilder.WithNewtonsoftJson(Action<NewtonsoftServiceHubProtocolOptions> configure)

이 메서드는 Newtonsoft.Json 사용자만 사용할 수 있습니다. 다음은 카멜 대/소문자 이름을 사용하는 샘플입니다.

var serviceManager = new ServiceManagerBuilder()
    .WithNewtonsoftJson(o =>
    {
        o.PayloadSerializerSettings = new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver()
        };
    })
    .BuildServiceManager();
ServiceManagerOptions.JsonSerializerSettings(사용되지 않음)

이 메서드는 일시적인 전송 유형에만 적용됩니다. 이것을 사용하지 마십시오.

var serviceManager = new ServiceManagerBuilder()
    .WithOptions(o =>
    {
        o.JsonSerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
    })
    .BuildServiceManager();

메시지 팩 serialization

  1. Microsoft.AspNetCore.SignalR.Protocols.MessagePack 패키지를 설치해야 합니다.

  2. 기본 JSON 프로토콜과 함께 MessagePack 프로토콜을 추가하려면 다음을 수행합니다.

    var serviceManagerBuilder = new ServiceManagerBuilder()
        .AddHubProtocol(new MessagePackHubProtocol());
    
  3. 허브 프로토콜을 완전히 제어하려면 다음을 사용할 수 있습니다.

        var serviceManagerBuilder = new ServiceManagerBuilder()
            .WithHubProtocols(new MessagePackHubProtocol(), new JsonHubProtocol());
    

    WithHubProtocols는 먼저 기존 프로토콜을 지우고 새 프로토콜을 추가합니다. 이 메서드를 사용하여 JSON 프로토콜을 제거하고 MessagePack만 사용할 수도 있습니다.

임시 모드의 경우 기본적으로 서비스 쪽은 JSON 페이로드를 MessagePack 페이로드로 변환하며 MessagePack을 지원하는 레거시 방법입니다. 그러나 이 레거시 방법이 예상대로 작동하지 않을 수 있으므로 MessagePack 허브 프로토콜을 명시적으로 추가하는 것이 좋습니다.

HTTP 요청 다시 시도

임시 모드의 경우 이 SDK는 요청이 멱등성이기만 하면 일시적인 오류가 발생할 때 자동으로 요청을 다시 전송하는 기능을 제공합니다. 이 기능을 사용하려면 ServiceManagerOptions.RetryOptions 속성을 사용할 수 있습니다.

특히 다음과 같은 유형의 요청이 다시 시도됩니다.

  • SignalR 클라이언트에 메시지를 보내는 메시지 요청의 경우 SDK는 HTTP 응답 상태 코드가 500보다 큰 경우 요청을 다시 시도합니다. HTTP 응답 코드가 500과 같으면 서비스 쪽의 시간 제한을 나타낼 수 있으며 요청을 다시 시도하면 메시지가 중복될 수 있습니다.

  • 그룹에 대한 연결 추가 등과 같은 기타 유형의 요청에서는 SDK가 다음 조건에서 요청을 다시 시도합니다.

    1. HTTP 응답 상태 코드가 5xx 범위에 있거나 상태 코드 408(요청 시간 제한)을 나타내며 요청 시간이 초과되었습니다.
    2. ServiceManagerOptions.HttpClientTimeout에 구성된 시간 제한 길이보다 더 긴 기간 동안 요청 시간이 초과되었습니다.

SDK는 멱등성 요청, 즉 반복되더라도 다른 효과가 없는 요청만 다시 시도할 수 있습니다. 요청이 멱등성이 아닌 경우 다시 시도를 수동으로 처리해야 할 수 있습니다.

다음 단계

이 문서에서는 애플리케이션에서 SignalR Service를 사용하는 방법을 알아봅니다. SignalR Service에 대해 자세히 알아보려면 다음 문서를 확인합니다.