通过核心 API 和后台服务从 Angular 进行轮询
Polling from Angular via Core API and Background Service
我正在尝试通过 BackgroundService 从 Angular 到 .NET Core API 进行轮询。
我将从调用 ApiController 的 Angular 组件传递输入,这将触发 BackgroundService 并且输出会定期更新回 Angular 组件。
我的问题很少。
- 我可以在没有任何外部库的情况下通过这种方式实现轮询吗?
- 如何给Worker传递参数
ExecuteAsync
?
- 如何通过GET调用后台服务API?
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);
})
}
}
这里有很多东西,但我想你只对呼叫工人感兴趣。
所以第一步。
在配置服务中
services.AddScoped();
在控制器构造函数中。
私有只读 ILogger _logger;
私有只读工人_worker;
public TestController(ILogger 记录器,Worker 工作者)
{
_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
注意:我怀疑这种方法不会给你更新,因为你正在等待请求完成,并且在此之前结果不会 return。
更新
For Longer 运行 以上方法的后台操作将不起作用。为此,您必须做更多的工作。
- 当Angular调用Api.
- 在某些 table 中创建一个工作项或使用唯一 ID 存储。
- Return Angular.
的唯一 ID
- 后台服务将根据存储中可用的数据工作,并在存储中保持更新状态。
- 基于 guid return 从 Api 到 Angular。
- 您可以调用另一个 api 函数来检查工作项的状态。
注意:如果您想避免轮询,则可以根据用例使用 SignalR 或 websocket。
我正在尝试通过 BackgroundService 从 Angular 到 .NET Core API 进行轮询。
我将从调用 ApiController 的 Angular 组件传递输入,这将触发 BackgroundService 并且输出会定期更新回 Angular 组件。
我的问题很少。
- 我可以在没有任何外部库的情况下通过这种方式实现轮询吗?
- 如何给Worker传递参数
ExecuteAsync
? - 如何通过GET调用后台服务API?
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);
})
}
}
这里有很多东西,但我想你只对呼叫工人感兴趣。
所以第一步。
在配置服务中 services.AddScoped();
在控制器构造函数中。
私有只读 ILogger _logger; 私有只读工人_worker; public TestController(ILogger 记录器,Worker 工作者) { _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
注意:我怀疑这种方法不会给你更新,因为你正在等待请求完成,并且在此之前结果不会 return。
更新
For Longer 运行 以上方法的后台操作将不起作用。为此,您必须做更多的工作。
- 当Angular调用Api.
- 在某些 table 中创建一个工作项或使用唯一 ID 存储。
- Return Angular. 的唯一 ID
- 后台服务将根据存储中可用的数据工作,并在存储中保持更新状态。
- 基于 guid return 从 Api 到 Angular。
- 您可以调用另一个 api 函数来检查工作项的状态。
注意:如果您想避免轮询,则可以根据用例使用 SignalR 或 websocket。