Потоковый текст в Dart с Redstone/Shelf
Мне просто пришло в голову, что имеет смысл потоковую передачу строк, каждая из которых представляет элемент из запроса к базе данных, а не возвращает весь их список в конце процесса, это может привести к первому результату ранее в браузере. Поэтому я попытался реализовать это с Redstone
который использует Shelf
, Вот мой основной тест
@app.Route ('/testStream')
testSream ()
{
StreamController<String> controller = new StreamController<String> ();
() async
{
var initialTime = new DateTime.now();
await new Future.delayed (new Duration (seconds: 1));
controller.add("hello\n");
await new Future.delayed (new Duration (seconds: 10));
controller.add("chao\n");
var finalTime = new DateTime.now().difference(initialTime);
controller.add(finalTime.toString());
controller.close();
}();
Stream<List<int>> intStream = controller.stream.map((s) => s.codeUnits);
return new shelf.Response.ok (intStream);
}
Просто для некоторого контекста, связанные парни используют "потоковую передачу текста" в шаблоне, который они получили от Facebook, для быстрой визуализации частей страницы и вставки некоторых последних (по мере возможности), они реализуют это в Playframework (Scala), где они используют Enumerables
которые ведут себя так же, как потоки дартс. Вы можете увидеть это в этом видео.
Проблема с моим кодом в том, что пока я ожидал, что он покажет "hello"
через 1 секунду и "chao"
10 секунд спустя То, что я получаю, это 11 секунд ожидания, а затем полный текст. Как видите, я отвечаю Shelf.Response
с Stream<List<int>>
где каждый List<int>
это просто строка из исходного потока, преобразованная в байты.
Это проблема / особенность шельфа, или Редстоун возится с ответом и превращает его в будущее? Есть ли работа вокруг?
РЕДАКТИРОВАТЬ
Что я хочу получить
Ничего за 1 секунду.
Через 1 секунду
hello
Через 11 секунд
hello
chao
0:00:11.009000
Что я действительно получаю
Ничего за 1 секунду.
Через 11 секунд
hello
chao
0:00:11.009000
1 ответ
Для тех, кто придет позже:
Как предложил @Pacane в комментарии к вопросу, ссылка (https://github.com/dart-lang/shelf/issues/54), которую он разместил, действительно содержит комментарий Андерсмхольмгрена, который подходит для этой проблемы:
return new Response.ok(counterStream, context: {"shelf.io.buffer_output": false});
Установка для параметра «shelf.io.buffer_output» значения false отключает выходной буфер Shelf и делает так, что байты, добавляемые в поток ответа, отправляются напрямую по сети клиенту.