Question

I would like to have simple API in my http server so everytime I write to HttpResponse I use stream.

so I convert all object into stream, ie 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;
}

and later

(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());

but I get error

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)

Im not sure what I am doing wrong here. I saw examples where File's input stream was piped to response but I cannot make it work either.

any help appreciated!

Was it helpful?

Solution

There are a couple of things to note here:

First, the JSON and UTF8 encoders will produce a single value when you're calling encode(), so you'll be creating a Stream of just a single value. I wonder how much value you get from that.

Second, your Stream doesn't actually get any values. onListen is called when the first listener subscribes, but any value returned from onListen isn't used for anything. To create a Stream from a single value you probably want to use new Stream.fromIterable():

<List<int>> toStream(Object value) =>
    new Stream.fromIterable([UTF8.encode(JSON.encode(value))])

So that should cause a value to actually get into the Stream, and take care of your error. I think the source of you error is that the input stream is not closed, and creating it from an Iterable will close the Stream when the Iterable is exhausted.

pipe() should also now work, so you can try this:

toStream({"a": 1, "B": 2}).pipe(response)
  .then((_) {
    print("done");
  });

All said though, I don't see how this is better than:

response
  ..write(JSON.encode(value))
  ..close();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top