Потоковая передача ответа в веб-API ASP.NET Core 6, работающем локально, но не в веб-приложении Azure, размещенном в Windows

Я запускаю службу как веб-приложение Azure. Проблема в том, что поток ответов не принимается в том виде, в котором он отправляется приложением, а поступает большими порциями. Я предполагаю, что это связано с буферизацией ответов. Мой веб-API ASP.NET Core 6 размещен в IIS в ОС Windows в веб-приложении Azure.

Все работает локально (с использованием локального хостинга IIS), но не в размещенной среде.

Я пробовал следующее:

  1. Отключена буферизация ответов в промежуточном программном обеспечении.
var responseBodyFeature = context.Features.Get<IHttpResponseBodyFeature>();

if (responseBodyFeature != null)   
    responseBodyFeature.DisableBuffering();
  1. Установите заголовки ответов, добавив web.config в мой веб-API ASP.NET Core 6:

     <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> 
    
  2. Я проверил, что между ними нет APIM или прокси-сервера, которые могут вызвать буферизацию ответа.

    У меня есть следующий код в моем веб-API ASP.NET Core 6:

     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();
         }
     }
    
  3. Это также рассматривается ниже, но я не хочу, чтобы это затрагивало другие конечные точки, не связанные с потоковой передачей:

     .UseKestrel(options =>
                 {
                     options.Limits.MaxResponseBufferSize = 2000
                 });
    

Ниже приведен код на стороне клиента, вызывающий веб-API ASP.NET Core 6:

        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.info(value);                
        }
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
Как установить LAMP Stack 1/2 на Azure Linux VM
Как установить LAMP Stack 1/2 на Azure Linux VM
В дополнение к нашему предыдущему сообщению о намерении Azure прекратить поддержку Azure Database для MySQL в качестве единого сервера после 16...
0
0
234
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы должны добиться успеха, если установите для заголовка ответа Transfer-Encoding значение identity.

Вы можете сделать это в своем web.config или в коде.

Он установлен на «куски»

s_v 19.04.2024 03:00

@s_v Если вы хотите преодолеть это, просто установите в коде значение «идентичность».

Architect Jamie 19.04.2024 17:20

Потоковая передача работала с моим кодом, проблема была в специальном промежуточном программном обеспечении для ведения журнала, которое ожидало полного ответа, прежде чем вернуться к пользователю. Я отключил это промежуточное программное обеспечение, и оно начало работать.

s_v 25.04.2024 10:09
Ответ принят как подходящий

Проблема для меня заключалась в том, что промежуточное программное обеспечение для регистрации ждало регистрации всего результата. Итак, мой код для потоковой передачи был правильным, и простое удаление этого промежуточного программного обеспечения заставило его работать. Поэтому сначала вам следует проверить наличие таких блокирующих промежуточных программ!

Мой код для потоковой передачи в контроллере –

 await foreach (var streamingCompletions in azResponse.WithCancellation(cancellationToken))
    {
        var data = streamingCompletions.Choices.Select(x => x.Text);
        string myFinalString = string.Join("", data);
        var sseMessage = $"{System.Text.Json.JsonSerializer.Serialize(myFinalString)}";
        await Response.Body.WriteAsync(Encoding.UTF8.GetBytes(sseMessage));
        await Response.Body.FlushAsync();
    }

return new EmptyResult();

Другие вопросы по теме

Похожие вопросы

Несколько хранилищ ключей Azure, связанных с одной и той же конфигурацией приложения, приводят к ошибке аутентификации в приложении весенней загрузки
Не удалось выполнить правильные действия по копированию данных контейнера BLOB-объектов в ADF в двух разных подписках в одном клиенте
В Applicaition Insights данные не отображаются
Создайте токен доступа для перечисления пользователей группы с помощью Graph Explorer или Postman
Сервер OAuth API Manager генерирует неверную заявку на аудиторию
Скопируйте данные общего доступа между подписками — здесь целевая подписка находится в виртуальной сети
Как получить размер ключа существующего ключа хранилища ключей Azure?
Как скопировать данные общего доступа между подписками учетных записей хранения — сценарий приведен в описании
Веб-приложение (Linux) — BadGateway/Запрещено — подписке не разрешено создавать или обновлять ферму серверов
Отправленные данные в хранилище Datalake