簡體   English   中英

通過核心 API 和后台服務從 Angular 輪詢

[英]Polling from Angular via Core API and Background Service

我正在嘗試通過 BackgroundService 從 Angular 到 .NET Core API 進行輪詢。

我將傳遞來自 Angular 組件的輸入,該組件調用 ApiController 並將觸發 BackgroundService,並且輸出會頻繁更新回 Angular 組件。

我有幾個疑問。

  1. 我可以在沒有任何外部庫的情況下以這種方式實現輪詢嗎?
  2. 如何將參數傳遞給 Worker ExecuteAsync
  3. 如何通過GET API調用BackgroundService?

ApiController

[ApiController]
[Route("[controller]")]
public class TestController : ControllerBase
{
    private readonly ILogger<TestController> _logger;

    public TestController(ILogger<TestController> logger)
    {
        _logger = logger;
    }

    [HttpGet]
    public async Task<JsonResult> Get(CancellationToken cancellationToken)
    {
        var output = await Worker   //How to call the worker here and then return the output?
        return new JsonResult(output);
    }
}

工人

public class Worker : BackgroundService
{
    private readonly ILogger<Worker> _logger;

    public Worker(ILogger<Worker> logger)
    {
        _logger = logger;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
            await Task.Delay(1000, stoppingToken);
            
           // Process inputs and return outputs in frequent intervals
        }
    }
}

Angular 組件

import { Component, Inject } from '@angular/core';
import { FormBuilder, FormGroup, FormControl, Validators } from '@angular/forms';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
})
export class HomeComponent {

  public testForm: FormGroup;
  public test = new  FormControl('1');
  
  constructor(private fb: FormBuilder,
    http: HttpClient, @Inject('BASE_URL') baseUrl: string) {

    const result = interval(2000)
    .pipe(
      switchMap(() => http.get(baseUrl + 'test')),
      map(res => res))

    result.subscribe(res => {
       this.x.setValue(res);
    })
  }
}

這里有很多東西,但我認為你只對 Calling worker 感興趣。

所以第一步。

  1. 在 ConfigureService services.AddScoped();

  2. 在 Controller 構造函數中。

    私有只讀 ILogger _logger; 私有只讀 Worker _worker; public TestController(ILogger logger,Worker worker) { _logger = logger; _worker = 工人; }

     [HttpGet] public async Task<JsonResult> Get(CancellationToken cancellationToken) { var output = await; //start worker return new JsonResult(output); }

啟動worker有兩種方法。 如果您從后台服務繼承,則調用 StartAsync。 如果您已經實現了 IHostedService,那么您必須自己實現。 https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-3.1&tabs=visual-studio

注意:我懷疑這種方法不會為您提供更新,因為您正在等待請求完成並且在該結果不會返回之前。

更新

對於更長時間運行的后台操作,上述方法將不起作用。 為此,您必須做更多的工作。

  1. 當 Angular 調用 Api。
  2. 在某個表或具有唯一 ID 的存儲中創建一個工作項。
  3. 將該唯一 ID 返回給 Angular。
  4. 后台服務將根據存儲中可用的數據工作,並將更新狀態保存在存儲中。
  5. 基於從 Api 返回到 Angular 的 guid。
  6. 您可以調用另一個 api function 來檢查工作項的狀態。

注意:如果要避免輪詢,則可以根據用例使用 SignalR 或 websocket。

暫無
暫無

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

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