Blazor .NET Core 3 uygulamasında Azure SignalR Hizmetine bağlanan SignalR .NET İstemcisi


11

ASP.NET Core 3.0 Blazor (sunucu tarafı) uygulaması ile Azure SignalR Hizmeti arasında bağlantı kurmaya çalışıyorum. Sonunda SignalR istemcimi (hizmetini) birkaç Blazor bileşenine enjekte edeceğim, böylece UI / DOM'umu gerçek zamanlı olarak güncelleyecekler.

Benim sorunum .StartAsync()hub bağlantısı yöntemimi çağırdığımda aşağıdaki iletiyi alıyorum olmasıdır :

Yanıt durum kodu başarıyı göstermiyor: 404 (Bulunamadı).

BootstrapSignalRClient.cs

Bu dosya, URL, bağlantı dizesi, anahtar, yöntem adı ve hub adı dahil SignalR Hizmeti için yapılandırmamı yükler. Bu ayarlar statik sınıfta yakalanır SignalRServiceConfigurationve daha sonra kullanılır.

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);
    }
}

NETR ile NETR ile deneyim kullanma deneyimim var, bu yüzden Startup.csdosyayı kullanarak .AddSignalR().AddAzureSignalR()ve uygulama yapılandırmasında bir hub eşleştirin ve bu şekilde yapmak belirli 'yapılandırma' parametreleri (yani bağlantı dizesi) kurulmasını gerektirir.

HubConnectionBuilderDurumum göz önüne alındığında , bağlantı dizesini veya SignalR Hizmeti'nde kimlik doğrulaması yapmak için bir anahtarı nereden alır?

404 mesajının eksik anahtar / bağlantı dizesinin bir sonucu olması mümkün müdür?


1
.WithUrl(signalRConfig.Url + signalRConfig.HubName)Bunun doğru URL ile sonuçlandığını doğrulayabilir misiniz? (Kesme noktası veya kayıt ile mi?)
Fildor

Ben Uri üs olarak Urive Uri (Uri, dize)
Fildor

ilginç bir şekilde 'kırmızı ringa balığı' idi ve 404 ile ilgisi yoktu.
Jason Shave

Yanıtlar:


8

Tamam, belgelerin burada önemli bir bilgi eksik olduğu ortaya çıktı. Azure SignalR Hizmetine bağlanan .NET SignalR İstemcisi'ni kullanıyorsanız, bir JWT belirteci istemeniz ve hub bağlantısı oluştururken sunmanız gerekir.

Bir kullanıcı adına kimlik doğrulaması yapmanız gerekiyorsa bu örneği kullanabilirsiniz .

Aksi takdirde, sizin için bir JWT jetonunu ve istemci URL'sini geri almak üzere Azure İşlevi gibi bir web API kullanarak bir "/ müzakere" uç noktası ayarlayabilirsiniz; Bu benim kullanım durumum için yaptığım şeydi. JWT jetonunuzu ve URL'nizi almak için bir Azure İşlevi oluşturma hakkında bilgi burada bulunabilir .

Bu iki değeri tutmak için bir sınıf oluşturdum:

SignalRConnectionInfo.cs

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

Ayrıca içinde bir yöntem oluşturdum SignalRService , Azure'da web API'sının "/ pazarlık" uç noktası, hub bağlantısının başlatılması ve iletileri almak için bir etkinlik + temsilcisinin kullanımı ile etkileşimi işlemek için :

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();
}

functionsClientBasitçe kesinlikle yazılı olduğu HttpClientbir taban URL ile önceden yapılandırılmış ve FunctionsClientConstants.SignalRtemel URL'ye eklenir "/ müzakere" yolu ile statik bir sınıftır.

Bir kez bu tüm kurmak vardı aradım await hubConnection.StartAsync();ve "bağlı"!

Tüm bunlardan sonra ReceiveMessage(aynı SignalRClient.cs) aşağıdaki gibi bir statik olay ve delege kurmak :

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

Son olarak, ReceiveMessagetemsilciyi uyguladım :

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 ekibine belge güncellemeleri sağladım ve bunun başkalarına yardımcı olacağını umuyorum!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.