Search code examples
httpdartdata-stream

Close stream after all data has been recieved


I am trying to make an HTTP request (I realise there is an http package that would probably make this easier but I want to learn how to do it with dart:io). My code below successfully prints out index.html from example.com, except the program runs forever, I assume because it is continues listening for data from the response. How do I stop the listener once all the data has been received from the stream? I assume I need to pass a handler to the onDone argument but I'm not sure what. I tried calling response.detachSocket() as per below, as that was the only logical seeming thing I could find, but it didn't work. If it's not obvious, I'm not totally sure what I'm doing here so any explanation would be greatly appreciated.

import 'dart:convert';
import 'dart:io';

main() async {
  var client = new HttpClient();
  var request = await client.getUrl(Uri.parse("http://www.example.com/"));
  var response = await request.close();
  response.transform(utf8.decoder).listen((data) {
    print(data);
  }, onDone: () => response.detachSocket());
}

Solution

  • You never close your HttpClient. Close it after you're done with it. The stream subscription will close itself when it's done, the onDone handler is a convenient way to run code when a stream completes, it's not necessary to use it to close the stream.

    import 'dart:convert';
    import 'dart:io';
    
    main() async {
      var client = new HttpClient();
      var request = await client.getUrl(Uri.parse("http://www.example.com/"));
      var response = await request.close();
      response.transform(utf8.decoder).listen((data) {
        print(data);
      }, onDone: () => response.detachSocket());
      client.close();
    }
    

    There is also no need to detach the socket.


    You could even call client.close earlier with the force parameter set to false, which is the default:

    main() async {
      var client = new HttpClient();
      var request = await client.getUrl(Uri.parse("http://www.example.com/"));
      client.close();
      var response = await request.close();
      response.transform(utf8.decoder).listen((data) {
        print(data);
      });
    }