聊聊如何快速实现异步轮询 Web API

2024年 5月 23日 56.8k 0

在现代Web开发中,异步处理已经成为提升应用性能和用户体验的关键技术之一。特别是在处理需要较长时间完成的操作时,如文件上传、大数据处理或第三方服务调用,异步处理能够有效避免客户端的长时间等待,提高系统的吞吐量和响应速度。本文将介绍如何使用异步轮询Web API快速实现这一功能,并提供相应的代码示例。

聊聊如何快速实现异步轮询 Web API-1

一、异步轮询模式介绍

异步轮询模式是一种客户端定期向服务器查询任务状态的设计模式。其基本流程如下:

  • 客户端向Web API发起请求。
  • Web API接收请求后立即返回一个“任务ID”,并开始后台异步处理任务。
  • 客户端使用返回的“任务ID”定期向Web API发送查询请求,以获取任务的处理进度和状态。
  • 当任务完成后,Web API将结果保存在某个位置,并更新任务状态为“完成”。
  • 客户端查询到任务完成后,再向Web API发送获取结果的请求。

二、使用Hangfire和AsyncFlow快速实现

为了简化异步轮询模式的实现,我们可以利用Hangfire和AsyncFlow这两个开源库。Hangfire是一个后台任务调度库,可以将任何方法转换为后台任务,并将任务状态和结果持久化。AsyncFlow则是一个异步轮询Web API生成器,可以根据Hangfire的任务自动创建异步轮询的API端点。

步骤一:安装必要的NuGet包

首先,你需要在你的ASP.NET Core项目中安装以下几个NuGet包:

  • Hangfire.AspNetCore
  • Hangfire.MemoryStorage(或使用其他存储后端,如Hangfire.SqlServer)
  • AsyncFlow

步骤二:配置Hangfire和AsyncFlow

在Startup.cs中配置Hangfire和AsyncFlow:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        // 配置Hangfire使用内存存储(生产环境建议使用更稳定的存储后端)
        services.AddHangfire(configuration => configuration.UseMemoryStorage());
        services.AddHangfireServer();
        
        // 配置AsyncFlow
        services.AddAsyncFlow();
        
        // 其他服务配置...
    }
    
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        // 其他中间件配置...
        
        // 添加Hangfire的仪表盘(可选)
        app.UseHangfireDashboard();
        
        // 配置AsyncFlow的路由
        app.UseAsyncFlow();
        
        // 其他配置...
    }
}

步骤三:定义后台任务

定义一个需要异步处理的任务方法,并使用Hangfire的BackgroundJob.Enqueue方法将其加入后台任务队列:

public class MyLongRunningTask
{
    public void PerformTask(string taskId)
    {
        // 模拟长时间运行的任务
        Thread.Sleep(10000); // 假设任务需要10秒钟完成
        // 任务完成后,可以将结果保存到某个存储中,例如数据库或缓存。
    }
}

在API控制器中触发任务:

[ApiController]
[Route("[controller]")]
public class MyController : ControllerBase
{
    private readonly IBackgroundJobClient _jobClient;
    
    public MyController(IBackgroundJobClient jobClient)
    {
        _jobClient = jobClient;
    }
    
    [HttpPost]
    public IActionResult StartTask()
    {
        string taskId = Guid.NewGuid().ToString(); // 生成唯一的任务ID
        _jobClient.Enqueue(x => x.PerformTask(taskId)); // 加入后台任务队列
        return Ok(taskId); // 返回任务ID给客户端
    }
}

步骤四:客户端轮询

客户端在接收到任务ID后,可以定期向AsyncFlow生成的轮询API发送请求,以获取任务状态。当任务完成后,再请求获取结果。

客户端代码示例(使用JavaScript和Fetch API):

async function pollTask(taskId, interval = 2000) {
    let isCompleted = false;
    while (!isCompleted) {
        await new Promise(resolve => setTimeout(resolve, interval)); // 等待一定时间后再次轮询
        const response = await fetch(`/async-flow/status/${taskId}`); // 发送轮询请求到AsyncFlow的状态API
        const data = await response.json();
        if (data.status === 'completed') {
            isCompleted = true; // 任务完成,退出轮询循环
            // 可以在这里发送获取结果的请求,例如:fetch(`/results/${taskId}`)
            console.log('Task completed!');
        } else {
            console.log('Task still running...');
        }
    }
}

// 假设从服务器获取到了任务ID '12345'
pollTask('12345'); // 开始轮询任务状态

三、总结

通过使用Hangfire和AsyncFlow,我们可以快速实现异步轮询Web API,从而优化用户体验和系统性能。在实际应用中,你可能还需要考虑任务失败重试、结果存储与检索、安全性等方面的细节。希望本文能为你提供一个良好的起点,助你在异步编程的道路上更进一步。

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论