我想在我的http服务器中使用简单的API,所以每次写HttpResponse我都会使用流。
所以我将所有对象转换为流,即object-> json-> stream
Stream<List<int>> toStream(Object value) {
var json = JSON.encode(value);
var controller = new StreamController<List<int>>(onListen: () => UTF8.encode(json));
return controller.stream;
}
以后
(response as HttpResponse).addStream(toStream({"a": 1, "B": 2})
.then(() => response.flush())
.catchError((e, stack) {
_logger.error("Handling ${context.path} finished with an error: $e");
_logger.debug(stack.toString());
})
.whenComplete(() => response.close());
但我收到错误
Uncaught Error: Bad state: StreamSink is bound to a stream
Stack Trace:
#0 _StreamSinkImpl.close (io_sink.dart:122)
#1 _HttpOutboundMessage.close (http_impl.dart:481)
我不确定我在这里做错了什么。我看到了File的输入流被传送到响应的示例,但我也无法使其工作。
任何帮助表示赞赏!
答案 0 :(得分:2)
这里有几点需要注意:
首先,当您调用encode()
时,JSON和UTF8编码器将生成单个值,因此您将创建仅包含单个值的Stream。我想知道你从中获得多少价值。
其次,您的Stream实际上并未获得任何值。第一个侦听器订阅时会调用onListen
,但onListen
返回的任何值都不会用于任何事情。要从单个值创建Stream,您可能希望使用new Stream.fromIterable()
:
<List<int>> toStream(Object value) =>
new Stream.fromIterable([UTF8.encode(JSON.encode(value))])
因此,应该使值实际进入Stream,并处理您的错误。我认为你的错误来源是输入流没有关闭,从Iterable创建它会在Iterable耗尽时关闭Stream。
pipe()
现在也可以使用,所以你可以试试这个:
toStream({"a": 1, "B": 2}).pipe(response)
.then((_) {
print("done");
});
尽管如此,我不知道这比这更好:
response
..write(JSON.encode(value))
..close();