0

我有一个本地运行的 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 来实现这种目标?
  • 如果上述答案是肯定的,那么我在做什么错误?

谢谢!

4

0 回答 0