简体   繁体   中英

How to call web services on Rikulo's dart stream server?

I've got a technical problem while trying to consume a restful web service on the Stream server.

I use HTTPClient.openUrl to retrieve a JSON response from another remote server but once the connection is opened, I can no longer write response(connect.response.write) to my browser client.

The error is listed as following:

    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)

Any one knows the correct way of calling web services on the stream server?

The key is you have to return Future, since your task (openUrl) is asynchronous. In your sample code, you have to do:

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

For more information, refer to Request Handling . To avoid this kind of mistake, I post a feature request here .

Here is a working sample:

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

Here's my original code:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM