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

