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를 사용하는 방법을 보여 줍니다.
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.Json
및 Newtonsoft.Json
과 같은 JSON serialization 라이브러리를 지원하고 모든 전송 형식에 적용하기 때문입니다. 일반적으로 편리한 JSON 구현 System.Text.Json
및 Newtonsoft.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
(사용되지 않음)
ServiceManagerOptions.JsonSerializerSettings
이 메서드는 일시적인 전송 유형에만 적용됩니다. 이것을 사용하지 마십시오.
var serviceManager = new ServiceManagerBuilder()
.WithOptions(o =>
{
o.JsonSerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
})
.BuildServiceManager();
메시지 팩 serialization
Microsoft.AspNetCore.SignalR.Protocols.MessagePack
패키지를 설치해야 합니다.기본 JSON 프로토콜과 함께 MessagePack 프로토콜을 추가하려면 다음을 수행합니다.
var serviceManagerBuilder = new ServiceManagerBuilder() .AddHubProtocol(new MessagePackHubProtocol());
허브 프로토콜을 완전히 제어하려면 다음을 사용할 수 있습니다.
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가 다음 조건에서 요청을 다시 시도합니다.
- HTTP 응답 상태 코드가 5xx 범위에 있거나 상태 코드 408(요청 시간 제한)을 나타내며 요청 시간이 초과되었습니다.
ServiceManagerOptions.HttpClientTimeout
에 구성된 시간 제한 길이보다 더 긴 기간 동안 요청 시간이 초과되었습니다.
SDK는 멱등성 요청, 즉 반복되더라도 다른 효과가 없는 요청만 다시 시도할 수 있습니다. 요청이 멱등성이 아닌 경우 다시 시도를 수동으로 처리해야 할 수 있습니다.
다음 단계
이 문서에서는 애플리케이션에서 SignalR Service를 사용하는 방법을 알아봅니다. SignalR Service에 대해 자세히 알아보려면 다음 문서를 확인합니다.