如何在.NET 5 Web API中创建定期推送数据的GET订阅路由
实现方案
完全可以通过ASP.NET Core原生的流式响应实现你要的效果,不需要引入SignalR等额外组件,逻辑和你给出的Node示例完全对齐。
原代码问题
你当前的写法返回OkResult后,ASP.NET Core会直接标记响应已完成,无法再后续推送数据,需要修改为直接操作响应流,不要提前结束响应。
可运行实现代码
方案1:直接操作响应流(和Node示例逻辑完全一致)
[ApiController] [Route("[controller]")] public class MyController : ControllerBase { [HttpGet] public async Task Get(CancellationToken cancellationToken) { // 配置响应头,和Node示例参数保持一致 Response.ContentType = "application/x-ndjson"; Response.StatusCode = 200; // 立即发送响应头到客户端 await Response.StartAsync(cancellationToken); while (!cancellationToken.IsCancellationRequested) { // 序列化要推送的业务数据,这里以当前时间为例 var jsonData = System.Text.Json.JsonSerializer.Serialize(DateTime.Now); // 写入数据 + 换行符,符合ndjson格式规范 await Response.WriteAsync($"{jsonData}\n", cancellationToken); // 强制刷新缓冲区,立即将数据推送到客户端,避免缓存 await Response.Body.FlushAsync(cancellationToken); // 间隔5秒推送下一次 await Task.Delay(5000, cancellationToken); } } }
方案2:基于IAsyncEnumerable的更简洁写法
.NET 5+ 原生支持IAsyncEnumerable的流式序列化,框架会自动处理响应输出:
using System.Runtime.CompilerServices; [ApiController] [Route("[controller]")] public class MyController : ControllerBase { [HttpGet] [Produces("application/x-ndjson")] public async IAsyncEnumerable<string> Get([EnumeratorCancellation] CancellationToken cancellationToken) { while (!cancellationToken.IsCancellationRequested) { yield return System.Text.Json.JsonSerializer.Serialize(DateTime.Now) + "\n"; await Task.Delay(5000, cancellationToken); } } }
验证方式
项目启动后,运行命令curl -i http://localhost:你的端口号/My,就可以看到控制台每隔5秒输出一个时间戳,和你Node示例的效果完全一致。
注意事项
- 方法参数传入的
CancellationToken会在客户端主动断开连接时触发取消,避免服务端无意义的资源占用,必须加上 - 每次写入数据后必须手动刷新缓冲区,否则ASP.NET Core会默认攒够缓冲区大小才发送数据,无法达到实时推送的效果
- 该方案仅依赖原生GET路由实现,如果你不需要双向通信、自动重连等高级能力,完全可以替代SignalR使用
内容的提问来源于stack exchange,提问作者Question3r
相关产品推荐
相关产品推荐

