如何在Rikulo的dart流服务器上调用Web服务?

时间:2013-05-01 02:05:07

标签: dart rikulo

我在尝试在Stream服务器上使用restful Web服务时遇到了技术问题。

我使用HTTPClient.openUrl从另一台远程服务器检索JSON响应,但是一旦打开连接,我就不能再将响应(connect.response.write)写入浏览器客户端。

错误列如下:

    Unhandled exception:
    Bad state: StreamSink is closed
    #0      _FutureImpl._scheduleUnhandledError.<anonymous closure> (dart:async:325:9)
    #1      Timer.run.<anonymous closure> (dart:async:2251:21)
    #2      Timer.run.<anonymous closure> (dart:async:2259:13)
    #3      Timer.Timer.<anonymous closure> (dart:async-patch:15:15)
    #4      _Timer._createTimerHandler._handleTimeout (dart:io:6730:28)
    #5      _Timer._createTimerHandler._handleTimeout (dart:io:6738:7)
    #6      _Timer._createTimerHandler.<anonymous closure> (dart:io:6746:23)
    #7      _ReceivePortImpl._handleMessage (dart:isolate-patch:81:92)

任何人都知道在流服务器上调用Web服务的正确方法吗?

2 个答案:

答案 0 :(得分:2)

关键是你必须返回Future,因为你的任务(openUrl)是异步的。在您的示例代码中,您必须执行以下操作:

return conn.then((HttpClientRequest request) {
//^-- notice: you must return a future to indicate when the serving is done

有关详细信息,请参阅Request Handling。为了避免这种错误,我发布了a feature request here

以下是一份工作样本:

library issues;

import "dart:io";
import "dart:uri";
import "package:rikulo_commons/io.dart" show IOUtil;
import "package:stream/stream.dart";

void main() {
  new StreamServer(uriMapping: {
    "/": (connect)
      => new HttpClient().getUrl(new Uri("http://google.com"))
      .then((req) => req.close())
      .then((res) => IOUtil.readAsString(res))
      .then((result) {
        connect.response.write(result);
      })
  }).start();
}

答案 1 :(得分:0)

这是我的原始代码:

void startProcess(HttpConnect connect){
  String method = "GET";

  String url = "http://XXXXXX/activiti-rest/service/deployments";

  Map authentication = {"username":"XXXXX", "password":"XXXXX"};
  Map body = {"XXXXX":"XXXXX", "XXXXX":"XXXXX"};

  processRequest(connect, method, url, authentication, body.toString());
}

void processRequest(HttpConnect connect, String method, String url, Map authentication, String body) {

  HttpClient client = new HttpClient();
  Uri requestUri = Uri.parse(url);

  Future<HttpClientRequest> conn = client.openUrl(method, requestUri);

  conn.then((HttpClientRequest request) {
    request.headers.add(HttpHeaders.CONTENT_TYPE, Constants.CONTENT_TYPE_JSON);
    // Add base64 authentication header, the class is contained in a separate dart file
    String base64 = Base64String.encode('${authentication["username"]}:${authentication["password"]}');
    base64 = 'Basic $base64';
    request.headers.add("Authorization",  base64);

    switch( method ) {
      case Constants.METHOD_GET: break;
      case Constants.METHOD_POST:
        body = body.replaceAllMapped(new RegExp(r'\b\w+\b'), (match) => '"${match.group(0)}"' );//no replacement for now
        request.write(body);
        break;
    }
    return request.close();
  })
  .then((HttpClientResponse response) {
    return IOUtil.readAsString(response);
  })
  .then((String result) {
    connect.response.write(result);
  });
}