我有一个本地运行的 asp.net 核心应用程序,我想在 Internet 上公开它。我正在使用 Azure 函数代理和混合连接。除了在无限循环中使用 WriteAsync 流式传输数据的端点之外,一切都很好。
我在一个小应用程序中重现了这个问题,并尝试解释。
控制器如下:
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
namespace StreamingCoreSimulation.Controllers
{
[ApiController]
[Route("[controller]")]
public class StreamingController : ControllerBase
{
private Random _random = new Random();
private readonly ILogger<WeatherForecastController> _logger;
public StreamingController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet("numbers")]
async public Task<IActionResult> Get()
{
HttpContext.Features.Get<IHttpResponseBodyFeature>().DisableBuffering();
return await Task.FromResult(new PushStreamResult(WriteToStreamAsync, "application/json"));
}
[HttpGet("test")]
public IActionResult Test()
{
return Ok("All Fine!");
}
async Task WriteToStreamAsync(Stream outputStream)
{
try
{
var exit = false;
while (true)
{
if (exit)
{
break;
}
var bytes = Encoding.UTF8.GetBytes(_random.Next().ToString());
using var memoryStream = new MemoryStream(bytes);
await memoryStream.CopyToAsync(outputStream);
await outputStream.WriteAsync(bytes, 0, bytes.Length);
byte[] newLine = Encoding.UTF8.GetBytes("\r\n");
await outputStream.WriteAsync(newLine, 0, newLine.Length);
await outputStream.FlushAsync();
System.Threading.Thread.Sleep(1000);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
outputStream.Close();
}
}
}
}
PushStreamResult 是:
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Net.Http.Headers;
using System;
using System.IO;
using System.Threading.Tasks;
namespace StreamingCoreSimulation
{
public class PushStreamResult : IActionResult
{
private readonly Func<Stream, Task> _onStreamAvailabe;
private readonly string _contentType;
public PushStreamResult(Func<Stream, Task> onStreamAvailabe, string contentType)
{
_onStreamAvailabe = onStreamAvailabe;
_contentType = contentType;
}
async public Task ExecuteResultAsync(ActionContext context)
{
var stream = context.HttpContext.Response.Body;
context.HttpContext.Response.GetTypedHeaders().ContentType = new MediaTypeHeaderValue(_contentType);
await _onStreamAvailabe(stream);
}
}
}
proxies.json 是:
{
"$schema": "http://json.schemastore.org/proxies",
"proxies": {
"streaming": {
"matchCondition": {
"route": "/streaming/{*path}"
},
"backendUri": "http://localhost:44333/streaming/{path}"
}
}
}
使用 Azure 函数代理,当我调用测试端点时响应是正确的,当我调用数字时响应等待。在while循环中放置一个断点,程序正在运行。如果我强制退出标志为true,循环停止并且所有生成的数字立即到达。
在本地运行相同的程序,数据在while循环期间到达:这也是我对 Azure Function Proxy 所做的。
我的问题是:
- 是否可以使用 Azure Function Proxy 来实现这种目标?
- 如果上述答案是肯定的,那么我在做什么错误?
谢谢!