簡體   English   中英

SignalR 客戶端-服務器連接問題

[英]SignalR client-server connection issue

我整天都在試圖找出問題所在,但無法弄清楚。 這是我的 SignalR 集線器( BlazorServerAppHub.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.SignalR;
    using BlazorServerApp.Data;
    
    namespace BlazorServerApp
    {
        public class BlazorServerAppHub: Hub
        {
            public const string HubUrl = "/chat";
      
            public async Task Broadcast(WeatherForecast[] forecasts)
            {
                await Clients.All.SendAsync("ReceiveMessage", forecasts);
            }
    
            public override Task OnConnectedAsync()
            {
                return base.OnConnectedAsync();
            }
        }
    }

這是業務邏輯頁面( WeatherForecastService.cs

using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
using BlazorServerApp.Data;
using Microsoft.Extensions.Hosting;
using System.Threading;
using System.Timers;

namespace BlazorServerApp.Data
{
    public class WeatherForecastService  
    {
        private readonly IHubContext<BlazorServerAppHub> _hubContext;

        public WeatherForecastService(IHubContext<BlazorServerAppHub> hubContext)
        {
            _hubContext = hubContext;
        }
        
        protected  async Task Broadcast()
        {
            var forecasts = await GetForecastAsync();
            await _hubContext.Clients.All.SendAsync("Broadcast", forecasts);
        }

        public Task<WeatherForecast[]> GetForecastAsync()
        {
            var rng = new Random();
        }    
                
    }

 public class WeatherForecast
    {
        public int A { get; set; }

    }
}

最后,這是我的 razor 頁面( FetchData.razor

@page "/fetchdata"

@using BlazorServerApp.Data;
@inject NavigationManager navigationManager
@using Microsoft.AspNetCore.SignalR.Client;

<h1>Weather forecast</h1>

<p>This component demonstrates fetching data from a service.</p>

@if (forecasts == null)
{
    <p><em>Loading...</em></p>
}
else
{

    <table class="table">
        <thead>
            <tr>
                <th>A</th>
               
            </tr>
        </thead>
        <tbody>
            @foreach (var forecast in forecasts)
            {
                <tr>
                    <td>@forecast.A</td>
                    
                </tr>
            }
        </tbody>
    </table>
}

@code {

    private  WeatherForecast[] forecasts;
    private HubConnection _hubConnection;

    protected override async Task OnInitializedAsync()
    {
        string baseUri = navigationManager.BaseUri;
        string hubUrl = baseUri.TrimEnd('/') + BlazorServerAppHub.HubUrl;

        _hubConnection = new HubConnectionBuilder().WithUrl(hubUrl).Build();
        _hubConnection.On< WeatherForecast[]>("Broadcast", forcast => { forecasts = forcast; StateHasChanged(); });

        await _hubConnection.StartAsync();
    }
}

基本上,我正在嘗試從服務器獲取數據並定期將其推送到客戶端。 當我在FetchData.razor中運行應用程序forecasts時,問題是我的頁面為空,因此頁面顯示“正在加載”。 這是為什么? 我的猜測是我在 SignalR 通信中遺漏了一些東西。

為了讓服務器定期將數據推送到客戶端,您需要運行某種后台服務。 有很多方法可以做到這一點,例如:

但是,由於您說您只想發送一次數據以進行測試,您可以連接到Hub.OnConnectedAsync()以在客戶端初始連接時將數據發送到客戶端。 首先,我建議為Task<WeatherForecast[]> GetForecastAsync()創建一個單獨的接口/存儲庫:

public interface IWeatherForecastRepository
{
    Task<WeatherForecast[]> GetForecastAsync();
}

public class WeatherForecastRepository
{
    private static readonly string[] Tickers = new[]
    {
        "10", "20", "30", "44", "77"
    };

    private static readonly int[] Ones = new[]
    {
        1000, 15000, 7000, 500, 2200
    };

    public Task<WeatherForecast[]> GetForecastAsync()
    {
        var rng = new Random();
        return Task.FromResult(Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            A = index,
            B = Tickers[index - 1],
            C = NextFloat(rng),
            D = Ones[index - 1],
            E = rng.Next(0, 10000),
        }).ToArray());
    }

    static float NextFloat(Random random)
    {
        double decimalPart = random.NextDouble();
        double intPart = random.Next(0, 1000);

        return (float)Math.Round(intPart + decimalPart, 3); ;
    }
}

然后,在向 DI 注冊該存儲庫后,您可以將其注入BlazorServerAppHub並在OnConnectedAsync()中使用它:

public class BlazorServerAppHub : Hub
{
    public const string HubUrl = "/chat";

    private readonly IWeatherForecastRepository _weatherForecastRepository;

    public BlazorServerAppHub(IWeatherForecastRepository weatherForecastRepository)
    {
        _weatherForecastRepository = weatherForecastRepository;
    }

    public async Task Broadcast(WeatherForecast[] forecasts)
    {
        await Clients.All.SendAsync("ReceiveMessage", forecasts);
    }

    public override async Task OnConnectedAsync()
    {
        await base.OnConnectedAsync();

        var forecasts = await _weatherForecastRepository.GetForecastAsync();

        // Clients.Caller will only send the data to the client that just connected
        await Clients.Caller.SendAsync("Broadcast", forecasts);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM