我将服务作为 Azure Web 应用程序运行。问题是响应流没有被接收,因为它们是由应用程序发送的,而是大块的。我的假设是这是由于响应缓冲造成的。我的 ASP.NET Core 6 Web API 托管在 Windows 操作系统上的 Azure Web 应用程序中的 IIS 上。
一切都在本地运行(使用本地 IIS 托管),但不在托管环境中运行。
我尝试过以下方法:
var responseBodyFeature = context.Features.Get<IHttpResponseBodyFeature>();
if (responseBodyFeature != null)
responseBodyFeature.DisableBuffering();
通过在我的 ASP.NET Core 6 Web API 中添加 web.config 来设置响应标头:
<httpProtocol>
<customHeaders>
<!-- Disable response buffering -->
<add name="Buffer" value="False" />
<add name="X-Accel-Buffering" value="no" />
<add name="Cache-Control" value="no-cache" />
</customHeaders>
</httpProtocol>
我已经检查过中间没有可能导致响应缓冲的 APIM 或代理。
我的 ASP.NET Core 6 Web API 中有以下代码:
await foreach (var streamingResponse in response.Response.WithCancellation(canToken))
{
foreach (var choice in streamingResponse.Choices)
{
yield return await Task.Run(() => choice.Text);
await Response.Body.FlushAsync();
}
}
也在下面考虑,但我不希望其他非流端点受到影响:
.UseKestrel(options =>
{
options.Limits.MaxResponseBufferSize = 2000
});
下面是调用 ASP.NET Core 6 Web API 的客户端代码:
let config = {
'method': "POST",
'cached': false,
headers: {
'Content-Type': 'application/json',
'Authorization': '<token>'
},
body: JSON.stringify(requestBody)
};
const response = await fetch(url, config);
const reader = response.body.pipeThrough(new TextDecoderStream()).getReader();
while (true) {
const { value, done } = await reader.read();
if (done) break;
console.log(value);
}
如果将 Transfer-Encoding 响应标头设置为
identity
,则应该会成功。
您可以在 web.config 或代码中完成此操作。