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.