我突然想到流式传输字符串是有意义的,每个字符串代表来自数据库查询的一个元素,而不是在过程结束时返回它们的整个列表,这可能会在浏览器上更早地获得第一个结果.所以我尝试用 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);
}
只是在某些情况下,Linked-in 的人使用他们从 Facebook 获得的模式中的“文本流”来快速呈现页面的一部分并插入一些后者(如果可用),他们在 Playframework (Scala) 中实现了这一点他们在哪里使用 Enumerables
这看起来就像 Dart 流一样。你可以在 this video 中看到它.
我的代码的问题在于,虽然我希望它显示 "hello"
1 秒 后,"chao"
10 秒 后。我得到的是 11 秒 的等待,然后是完整的文本。如您所见,我正在回复 Shelf.Response
用Stream<List<int>>
每个List<int>
只是将原始流中的字符串转换为字节。
这是 Shelf 问题/功能,还是 Redstone 搞乱了响应并将其转换为 future ?有什么解决办法吗?
编辑
我想得到什么
1 秒内没有任何内容。
1秒后
hello
11 秒后
hello
chao
0:00:11.009000
我真正得到了什么
1 秒内没有任何内容。
11 秒后
hello
chao
0:00:11.009000
最佳答案
对于那些后来到这里的人:
正如@Pacane 在问题评论中所建议的,他发布的链接 ( https://github.com/dart-lang/shelf/issues/54 ) 确实包含 Andersmholmgren 的评论,该评论适用于该问题:
return new Response.ok(counterStream, context: {"shelf.io.buffer_output": false});
将“shelf.io.buffer_output”选项设置为 false 会禁用 Shelf 的输出缓冲区,并使添加到响应流的字节直接通过网络发送到客户端。
关于dart - 使用 Redstone/Shelf 在 Dart 中流式传输文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29238873/