You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Linux版Azure App Service中启用Server Sent Events(SSE)的问题

在Linux版Azure App Service中启用Server Sent Events(SSE)的问题

问题背景

我正尝试在Linux版Azure App Service中启用Server Sent Events(SSE),但始终无法成功。查阅了大量教程,发现它们都只涉及编程层面的操作,而我认为问题出在服务器配置上。我的API中已经执行了以下操作:

  • 调用HttpContext IHttpResponseBodyFeature DisableBuffering()
  • 使用IHttpResponseBodyFeature.Writer
  • 返回符合要求的响应头

本地ASP.NET Core环境搭配Vue前端时,无需额外修改即可正常运行,但在Postman中测试时,服务器在首次写入后会返回ECONNRESET错误。我使用的是B1层级的App Service,理论上支持SSE。尝试过配置web.config(但Linux App Service似乎不使用IIS),还添加了responseBufferLimit参数,请问我还遗漏了什么配置?不想引入SignalR的额外开销,因此必须以当前方式实现。

相关代码

[HttpGet("ask/{question}")]
public async Task<IActionResult> Post(string question)
{
    var g = Response.HttpContext.Features.Get<Microsoft.AspNetCore.Http.Features.IHttpResponseBodyFeature>();
    g.DisableBuffering();
    Response.StatusCode = 200;
    Response.Headers.Add("Content-Type", "text/event-stream");
    Response.Headers.Add("Cache-Control", "no-cache");
    Response.Headers.Add("Connection", "keep-alive");

    var receivedBytes = Encoding.UTF8.GetBytes($"event: received\ndata: started processing\n\n");
    await g.Writer.WriteAsync(receivedBytes);
    await g.Writer.FlushAsync();
    //await Response.Body.WriteAsync(receivedBytes, 0, receivedBytes.Length);
    //await Response.Body.FlushAsync();

    var graphClient = new SimpleGraphClient(_graphUserService.GetToken());

    await foreach (var evDataTuple in _questionService.AskQuestion(question, graphClient, PlatformType.Web))
    {
        var eventData = $"event: {evDataTuple.ev}\ndata: {evDataTuple.data}\n\n";
        var bytes = Encoding.UTF8.GetBytes(eventData);

        //await Response.Body.WriteAsync(bytes, 0, bytes.Length);
        //await Response.Body.FlushAsync();
        await g.Writer.WriteAsync(bytes);
        await g.Writer.FlushAsync();
    }

    return new EmptyResult();
}

尝试过的web.config配置

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <location path="." inheritInChildApplications="false">
        <system.webServer>
            <handlers>
                <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" responseBufferLimit="0" />
            </handlers>
            <aspNetCore processPath="dotnet" arguments="" stdoutLogEnabled="false" stdoutLogFile="" hostingModel="inprocess" />
        </system.webServer>
    </location>
</configuration>

解决方案

  1. 删除无效的web.config:Linux版Azure App Service使用Kestrel而非IIS,web.config中的配置完全无效,直接删除该文件即可。
  2. 配置Kestrel禁用响应缓冲:在Program.cs中显式配置Kestrel的响应缓冲限制,确保输出能实时发送:
builder.WebHost.ConfigureKestrel(options =>
{
    options.Limits.MaxResponseBufferSize = 0;
});
  1. 禁用Azure ARR缓冲:通过Azure门户进入App Service的「应用程序设置」,添加以下两个配置项:
    • WEBSITE_DISABLE_ARR_AFFINITY 设置为 True
    • WEBSITE_DYNAMIC_CACHE 设置为 0
      这会禁用Application Request Routing的缓冲机制,避免截断SSE连接。
  2. 补充响应头:在Action中添加Transfer-Encoding: chunked头,明确告知服务器使用分块传输:
Response.Headers.Add("Transfer-Encoding", "chunked");
  1. 换用更可靠的测试工具:Postman对SSE的支持存在局限性,建议使用浏览器开发者工具或curl命令测试:
curl -N https://你的应用服务域名/api/ask/测试问题

内容的提问来源于stack exchange,提问作者Jasper B

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 21:58:27