Dart HttpClient.getUrl由Timer调用,没有客户端或http服务器

时间:2014-06-27 07:53:17

标签: dart server-side dart-async

编辑:问题与Timer或HttpServer无关,它是dart.io睡眠功能暂停所有内容。它在文档中清楚地描述,我的不好。

//

我在服务器代码中使用HttpClient时遇到了奇怪的问题。我打电话给

client.getUrl(Uri.parse(url)).then((HttpClientRequest response) => response.close()).then(HttpBodyHandler.processResponse).then((HttpClientResponseBody body) {
    print(body.response.statusCode);
从Timer对象

它永远不会到达打印步骤。 它几乎是以前版本的复制和粘贴代码,不是从Timer调用,而是从HttpRequest调用。工作代码在我的问题[这里] [1]。 它在长线上失败了,我怀疑它是它永远无法达到的最后一个未来(HttpClientResponseBody)。

Timer对象是这样创建的(只是测试代码):

main() {
  t = new Timer.periodic(new Duration(minutes: period), (Timer t) => hit());

}

void hit() {
  if (new DateTime.now().hour == 17) {
    print("syncing rock");

    loadUrlBody(furl + filter).then((content) {
      print("content loaded");

//编辑: 好吧,这里是来源,这可能是一些微不足道的问题......我两天都想不通:-D

import 'dart:async';
import 'dart:io';
import 'package:http_server/http_server.dart';
import 'package:slack/slack_io.dart' as slack;

Timer t;
bool check;
final period = 1;
final furl = "https://****.tpondemand.com";
final filter = "somefilter";


main() {
  t = new Timer.periodic(new Duration(minutes: period), (Timer t) => hit());

}

void hit() {
  if (new DateTime.now().hour == 17) {
    print("syncing rock");

    loadUrlBody(furl + filter).then((content) {
      print("content loaded");
      Map parsedMap = content.body;
      handleMap(parsedMap);
    });
    sleep(new Duration(minutes: 60));
  } else {
    print("no time to rock " + new DateTime.now().toString());
    sleep(new Duration(minutes: period * 10));
  }
}

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) {
    print(body.response.statusCode);
    c.complete(body);
  });
  return c.future;
}



void send2Slack(String m) {
  slack.Message message = new slack.Message()..text = m;

  slack.token = 'token';
  slack.team = 'team';
  slack.send(message);
}
void handleMap(Map valueMap) {

  final Duration lostInTime = new Duration(days: 30);
  var sb = new StringBuffer();
  sb.write('K o m p o s t \n');

  for (var item in valueMap["Items"]) {
    if (item['CreateDate'] == null) item['CreateDate'] = '/Date(1403167885000+0100)/';
    if (item['ModifyDate'] == null) item['ModifyDate'] = '/Date(1403167885000+0100)/';
    if (item['LastCommentDate'] == null) item['LastCommentDate'] = '/Date(1403167885000+0100)/';

    DateTime moonLanding = new DateTime.fromMillisecondsSinceEpoch(int.parse(item['CreateDate'].substring(6, 19)));
    DateTime modifyLanding = new DateTime.fromMillisecondsSinceEpoch(int.parse(item['ModifyDate'].substring(6, 19)));
    DateTime commentLanding = new DateTime.fromMillisecondsSinceEpoch(int.parse(item['LastCommentDate'].substring(6, 19)));
    DateTime lastChangeLanding = (modifyLanding.isBefore(commentLanding)) ? commentLanding : modifyLanding;
    Duration difference = new DateTime.now().difference(lastChangeLanding);

    if (moonLanding.add(lostInTime).isBefore(new DateTime.now()) && difference.inDays > 4) {
      sb
          ..write('<https://****.tpondemand.com/entity/')
          ..write(item['Id'])
          ..write('|')
          ..write(item['Name'])
          ..write('> last change: ')
          ..write(difference.inDays)
          ..write(' days ago \n');

    }
    ;


  }
  send2Slack(sb.toString());
  print("sent to Slack");
  sb.clear();
}

1 个答案:

答案 0 :(得分:0)

我创建了类似的代码,但我无法重现您的问题 因此,从Timer调用时,这基本上可行。

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

Timer t;
final period = 1;

void main(args) {
  t = new Timer.periodic(new Duration(minutes: period), (Timer t) => hit());
}

void hit() {
  loadUrlBody('http://www.google.com')
      .then((HttpClientResponseBody b) => print('hit: ${b.response.statusCode}'));
}

Future loadUrlBody(String url) {
  print('executing');
  HttpClient client = new HttpClient();
  // commented out because I have no server where I can use it
  // HttpClient client = new HttpClient()              
  //    ..addCredentials(Uri.parse("https://****.tpondemand.com/api"), "tprealm", new HttpClientBasicCredentials("user", "password"));
  return client.getUrl(Uri.parse(url))        // <== return is important here
      .then((HttpClientRequest response) => response.close())
      .then(HttpBodyHandler.processResponse)
      .then((HttpClientResponseBody body) {
        print('body: (${new DateTime.now()}) ${body.response.statusCode}');
        return body;                         // <== this value is the value the next 'then' receives. 
// for example x in: loadUrlBody('http://someurl').then(x) => doSomething(x)); 
      });
}

您不需要使用Completer。 Completer用于更复杂的用例,例如一个方法返回一个Completer,例如一个eventHandler完成它。

您必须确保在任何地方都返回Futurethen始终返回Future。返回的Future的值是then内返回的值。