HTTP服务器和Futures

HTTP服务器和Futures

本文介绍了Dart HTTP服务器和Futures的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图编写简单的HTTP服务器解析client.getUrl()的结果。我有一切工作,但我不能写回http请求对象(打印到控制台工作正常)。



相关代码是:

  main(){
HttpServer.bind(InternetAddress.ANY_IP_V4,4040)
.then((HttpServer server){
print $ {server.port}');
server.listen((HttpRequest request){
Future loadedContent = loadUrl(furl);
loadedContent.then((content)=> print内容));
// loadedContent.then((content)=> request.response.write(content));

request.response.close();
print(response closed);
});
})catchError((e)=> print(e.toString()));
}

问题是主函数在从Future获得结果之前结束通过打印在结果之前出现第二的响应关闭)。是否有办法等待主函数中的结果?



编辑:它与
我将重写我的代码,但如果有一个方法等待getUrl未来在main函数中,我更喜欢它。



编辑:my loadUrl

 未来的loadUrl url)
{
final c = new Completer();
HttpClient client = new HttpClient();
client.addCredentials(
Uri.parse(https://*****.tpondemand.com/api),
tprealm,
new HttpClientBasicCredentials *****,*****));
client.getUrl(Uri.parse(url))
.then((HttpClientRequest request){
//可选设置标头...
//可选写入请求对象...
//然后调用close。

return request.close();
})
.then((HttpClientResponse response){
//处理响应
//print(response.reasonPhrase);
response.transform(UTF8.decoder).listen((contents){
// handle data
map parsedMap = JSON.decode(contents);
c.complete(parsedMap);
//req.response.write(parsedMap[\"Items\"][0]);
});

});
return c.future;
}

上次编辑:这是工作代码

  import'dart:io'; 
import'dart:async';
import'package:http_server / http_server.dart';
import'dart:convert';

final furl =https://***.tpondemand.com;

未来的loadUrlBody(String url){
final c = new Completer();
HttpClient client = new HttpClient();
client.addCredentials(Uri.parse(https://***.tpondemand.com/api),tprealm,new HttpClientBasicCredentials(user,password));
client.getUrl(Uri.parse(url))
.then((HttpClientRequest response)=> response.close())
.then(HttpBodyHandler.processResponse)
.then((HttpClientResponseBody body){
c.complete(body);
});
return c.future;
}
main(){
final filter =/api/v1/Userstories?format=json&where=(Team.Id+eq+111111)&include=[Name, CreateDate,ModifyDate,LastCommentDate]& take = 1000;
HttpServer.bind(InternetAddress.ANY_IP_V4,4040).then((HttpServer server){
print('listen on localhost,port $ {server.port}');
server.listen ((HttpRequest request){
print(request.connectionInfo.remoteAddress);
loadUrlBody(furl + filter).then((content){
Map parsedMap = content.body;
// print(Map parsed);
request.response.write(parsedMap [Items]);
request.response.close();
// print响应关闭);
})。catchError((e)=> print(e.toString()));
} > print(e.toString()));
}


解决方案

c> loadUrl()返回未来(它可能应该),然后这应该工作

 HttpServer.bind(InternetAddress.ANY_IP_V4,4040)
.then((HttpServer服务器){
打印'listen on localhost,port $ {server.port}');
server.listen((HttpRequest request){
loadUrl(furl).then((){
// loadedContent。那么((content)=> print(content));
loadedContent.then((content)=> request.response.write(content));

request.response。 close();
print(response closed);
});
});
})catchError((e)=> print(e.toString ()));
}

更新

您需要修改 getData() loadUrl()方法

 未来getData(HttpRequest请求){//添加的返回类型Future(不必要)
return dao.findAll()。then((value){// added'return'
print(value);
});
}

更新2 b

 未来的loadUrl(String url)
{
// final c = new Completer //< == commented out
HttpClient client = new HttpClient();
client.addCredentials(
Uri.parse(https://*****.tpondemand.com/api),
tprealm,
new HttpClientBasicCredentials *****,*****));
return client.getUrl(Uri.parse(url))//< == added return
.then((HttpClientRequest request){
//可选设置标题...
//可选地写入请求对象...
//然后调用close。

return request.close();
})
。那么((HttpClientResponse response){
//处理响应
//print(response.reasonPhrase);
return response.transform(UTF8.decoder).listen( //< == added return
// handle data
Map parsedMap = JSON.decode(contents);
// c.complete(parsedMap); //< == commented out
//req.response.write(parsedMap[\"Items\"][0]);
})。asFuture(); //< == added` .asFuture()`

});
// return c.future; //< == commented out
}

通常情况下, return 在每次调用返回Future的方法之前,您可以避免使用完成器。完成者只适用于更复杂的情况(例如,当您从一个方法返回completer.future,但从其他地方完成它,例如一个事件处理程序)。


I am trying to write simple HTTP server which parse result of client.getUrl(). I've got everything working except I am not able to write back to http request object (print to console works fine).

Relevant code is:

main() {
  HttpServer.bind(InternetAddress.ANY_IP_V4, 4040)
      .then((HttpServer server) {
    print('listening on localhost, port ${server.port}');
    server.listen((HttpRequest request) {
      Future loadedContent = loadUrl(furl);
      loadedContent.then((content) => print(content));
  //  loadedContent.then((content) => request.response.write(content));

      request.response.close();
      print ("response closed");
    });
  }).catchError((e) => print(e.toString()));
}

Problem is that main function ends before I get result from Future (figured that out by printing "response closed" which appears second before results). Is there way to wait for results in main function?

Edit: It is related to Dart HttpRequest return futureI will rewrite my code, but if there is a way to wait for getUrl Future in main function, I would prefer it.

Edit: my loadUrl

Future loadUrl(String url)
{
  final c = new Completer();
  HttpClient client = new HttpClient();
  client.addCredentials(
          Uri.parse("https://*****.tpondemand.com/api"),
          "tprealm",
          new HttpClientBasicCredentials("*****", "*****"));
  client.getUrl(Uri.parse(url))
      .then((HttpClientRequest request) {
        // Optionally set up headers...
        // Optionally write to the request object...
        // Then call close.

        return request.close();
      })
      .then((HttpClientResponse response) {
        // Process the response.
        //print(response.reasonPhrase);
        response.transform(UTF8.decoder).listen((contents) {
             // handle data
            Map parsedMap = JSON.decode(contents);
            c.complete(parsedMap);
            //req.response.write(parsedMap["Items"][0]);
           });

      });
  return c.future;
  }

last edit: this is working code

import 'dart:io';
import 'dart:async';
import 'package:http_server/http_server.dart';
import 'dart:convert';

final furl = "https://***.tpondemand.com";

Future loadUrlBody(String url) {
  final c = new Completer();
  HttpClient client = new HttpClient();
  client.addCredentials(Uri.parse("https://***.tpondemand.com/api"), "tprealm", new HttpClientBasicCredentials("user", "password"));
  client.getUrl(Uri.parse(url))
      .then((HttpClientRequest response) => response.close())
      .then(HttpBodyHandler.processResponse)
      .then((HttpClientResponseBody body) {
       c.complete(body);
      });
  return c.future;
}
main() {
  final filter = "/api/v1/Userstories?format=json&where=(Team.Id+eq+111111)&include=[Name,CreateDate,ModifyDate,LastCommentDate]&take=1000";
  HttpServer.bind(InternetAddress.ANY_IP_V4, 4040).then((HttpServer server) {
    print('listening on localhost, port ${server.port}');
    server.listen((HttpRequest request) {
      print(request.connectionInfo.remoteAddress);
      loadUrlBody(furl + filter).then((content) {
        Map parsedMap = content.body;
        //print("Map parsed");
        request.response.write(parsedMap["Items"]);
        request.response.close();
        //print("response closed");
      }).catchError((e) => print(e.toString()));
    });
  }).catchError((e) => print(e.toString()));
}
解决方案

When your loadUrl() returns a Future (which it probably should) then this should work

main() {
  HttpServer.bind(InternetAddress.ANY_IP_V4, 4040)
      .then((HttpServer server) {
    print('listening on localhost, port ${server.port}');
    server.listen((HttpRequest request) {
      loadUrl(furl).then(() {
        // loadedContent.then((content) => print(content));
        loadedContent.then((content) => request.response.write(content));

        request.response.close();
        print ("response closed");
      });
    });
  }).catchError((e) => print(e.toString()));
}

update

You need to modify your getData() or loadUrl() method

Future getData(HttpRequest request) { // added return type 'Future' (not necessary)
  return dao.findAll().then((value) { // added 'return'
    print(value);
  });
}

update 2

Future loadUrl(String url)
{
  // final c = new Completer(); // <== commented out
  HttpClient client = new HttpClient();
  client.addCredentials(
          Uri.parse("https://*****.tpondemand.com/api"),
          "tprealm",
          new HttpClientBasicCredentials("*****", "*****"));
  return client.getUrl(Uri.parse(url))                      // <== added return
      .then((HttpClientRequest request) {
        // Optionally set up headers...
        // Optionally write to the request object...
        // Then call close.

        return request.close();
      })
      .then((HttpClientResponse response) {
        // Process the response.
        //print(response.reasonPhrase);
        return response.transform(UTF8.decoder).listen((contents) { // <== added return
             // handle data
            Map parsedMap = JSON.decode(contents);
            // c.complete(parsedMap); // <== commented out
            //req.response.write(parsedMap["Items"][0]);
           }).asFuture();  // <== added `.asFuture()`

      });
   // return c.future; // <== commented out
}

Normally it should be sufficient to prepend a return before each call to a method that returns a Future, then you can avoid using a completer. Completer are only for more complex situations (for example when you return the completer.future from one method but complete it from somewhere else, for example an event handler).

这篇关于Dart HTTP服务器和Futures的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-11 09:54