Blazor .NET Core 3 애플리케이션에서 Azure SignalR Service에 연결하는 SignalR .NET 클라이언트


11

ASP.NET Core 3.0 Blazor (서버 측) 응용 프로그램과 Azure SignalR 서비스를 연결하려고합니다. 최종적으로 몇 가지 Blazor 구성 요소에 SignalR 클라이언트 (서비스)를 주입하여 UI / DOM을 실시간으로 업데이트합니다.

내 문제는 .StartAsync()허브 연결에서 메서드를 호출 할 때 다음 메시지가 나타납니다 .

응답 상태 코드는 성공을 나타내지 않습니다 : 404 (찾을 수 없음).

BootstrapSignalRClient.cs

이 파일은 URL, 연결 문자열, 키, 메소드 이름 및 허브 이름을 포함하여 SignalR 서비스에 대한 구성을로드합니다. 이 설정은 정적 클래스에서 캡처되어 SignalRServiceConfiguration나중에 사용됩니다.

public static class BootstrapSignalRClient
{
    public static IServiceCollection AddSignalRServiceClient(this IServiceCollection services, IConfiguration configuration)
    {
        SignalRServiceConfiguration signalRServiceConfiguration = new SignalRServiceConfiguration();
        configuration.Bind(nameof(SignalRServiceConfiguration), signalRServiceConfiguration);

        services.AddSingleton(signalRServiceConfiguration);
        services.AddSingleton<ISignalRClient, SignalRClient>();

        return services;
    }
}

SignalRServiceConfiguration.cs

public class SignalRServiceConfiguration
{
    public string ConnectionString { get; set; }
    public string Url { get; set; }
    public string MethodName { get; set; }
    public string Key { get; set; }
    public string HubName { get; set; }
}

SignalRClient.cs

public class SignalRClient : ISignalRClient
{
    public delegate void ReceiveMessage(string message);
    public event ReceiveMessage ReceiveMessageEvent;

    private HubConnection hubConnection;

    public SignalRClient(SignalRServiceConfiguration signalRConfig)
    {
        hubConnection = new HubConnectionBuilder()
            .WithUrl(signalRConfig.Url + signalRConfig.HubName)
            .Build();            
    }

    public async Task<string> StartListening(string id)
    {
        // Register listener for a specific id
        hubConnection.On<string>(id, (message) => 
        {
            if (ReceiveMessageEvent != null)
            {
                ReceiveMessageEvent.Invoke(message);
            }
        });

        try
        {
            // Start the SignalR Service connection
            await hubConnection.StartAsync(); //<---I get an exception here
            return hubConnection.State.ToString();
        }
        catch (Exception ex)
        {
            return ex.Message;
        }            
    }

    private void ReceiveMessage(string message)
    {
        response = JsonConvert.DeserializeObject<dynamic>(message);
    }
}

.NET Core와 함께 SignalR을 사용한 경험 이있어서 앱 구성에서 허브를 Startup.cs사용 .AddSignalR().AddAzureSignalR()하고 허브를 사용 하여 파일 을 추가 하고이 방법으로 특정 '구성'매개 변수 (예 : 연결 문자열)를 설정해야합니다.

내 상황 HubConnectionBuilder에서 SignalR 서비스를 인증하기 위해 연결 문자열 또는 키를 어디서 얻습니까?

404 메시지가 누락 된 키 / 연결 문자열의 결과 일 수 있습니까?


1
.WithUrl(signalRConfig.Url + signalRConfig.HubName)이것이 올바른 URL을 초래하는지 확인할 수 있습니까? (브레이크 포인트 또는 로깅으로)
— Fildor

기본 Uri를 사용 Uri하고 Uri (Uri, string)
— Fildor

흥미롭게도 그것은 '빨간 청어'였고 404와는 아무 상관이 없었습니다.
— Jason Shave

답변:


8

자, 여기 문서에 중요한 정보가 부족하다는 것이 밝혀졌습니다. Azure SignalR 서비스에 연결하는 .NET SignalR 클라이언트를 사용하는 경우 허브 연결을 생성 할 때 JWT 토큰을 요청하고 제시해야합니다.

사용자 대신 인증해야하는 경우이 예제를 사용할 수 있습니다 .

그렇지 않으면 Azure 함수와 같은 웹 API를 사용하여 "/ 협상"엔드 포인트를 설정하여 JWT 토큰 및 클라이언트 URL을 검색 할 수 있습니다. 이것이 내가 유스 케이스를 위해했던 일입니다. JWT 토큰 및 URL을 얻기 위해 Azure Function을 만드는 방법에 대한 정보는 여기 에서 찾을 수 있습니다.

나는이 두 가지 값을 보유하기 위해 클래스를 만들었습니다.

SignalRConnectionInfo.cs

public class SignalRConnectionInfo
{
    [JsonProperty(PropertyName = "url")]
    public string Url { get; set; }
    [JsonProperty(PropertyName = "accessToken")]
    public string AccessToken { get; set; }
}

또한 SignalRServiceAzure에서 웹 API의 "/ negotiate"끝점과의 상호 작용, 허브 연결의 인스턴스화 및 다음과 같이 메시지 수신을위한 이벤트 + 대리자의 사용을 처리 하는 메서드를 만들었습니다 .

SignalRClient.cs

public async Task InitializeAsync()
{
    SignalRConnectionInfo signalRConnectionInfo;
    signalRConnectionInfo = await functionsClient.GetDataAsync<SignalRConnectionInfo>(FunctionsClientConstants.SignalR);

    hubConnection = new HubConnectionBuilder()
        .WithUrl(signalRConnectionInfo.Url, options =>
        {
           options.AccessTokenProvider = () => Task.FromResult(signalRConnectionInfo.AccessToken);
        })
        .Build();
}

은 functionsClient단순히 강력한 형식 인 HttpClient기본 URL 사전 구성과는 FunctionsClientConstants.SignalR기본 URL에 추가됩니다 "/ 협상"경로 정적 클래스입니다.

이 모든 설정이 완료되면 전화를했는데 await hubConnection.StartAsync();"연결됨"입니다.

이 모든 후 나는 정적 ReceiveMessage이벤트와 델리게이트를 다음과 같이 설정했다 SignalRClient.cs.

public delegate void ReceiveMessage(string message);
public static event ReceiveMessage ReceiveMessageEvent;

마지막으로 ReceiveMessage대리인을 구현했습니다 .

await signalRClient.InitializeAsync(); //<---called from another method

private async Task StartReceiving()
{
    SignalRStatus = await signalRClient.ReceiveReservationResponse(Response.ReservationId);
    logger.LogInformation($"SignalR Status is: {SignalRStatus}");

    // Register event handler for static delegate
    SignalRClient.ReceiveMessageEvent += signalRClient_receiveMessageEvent;
}

private async void signalRClient_receiveMessageEvent(string response)
{
    logger.LogInformation($"Received SignalR mesage: {response}");
    signalRReservationResponse = JsonConvert.DeserializeObject<SignalRReservationResponse>(response);
    await InvokeAsync(StateHasChanged); //<---used by Blazor (server-side)
}

Azure SignalR Service 팀에 설명서 업데이트를 다시 제공했으며 이것이 다른 사람에게 도움이되기를 바랍니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.