简体   繁体   English

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

[英]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. 尝试在Stream服务器上使用静态Web服务时遇到技术问题。

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. 我使用HTTPClient.openUrl从另一个远程服务器检索JSON响应,但是一旦打开连接,就无法再将响应(connect.response.write)写入我的浏览器客户端。

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? 有人知道在流服务器上调用Web服务的正确方法吗?

The key is you have to return Future, since your task (openUrl) is asynchronous. 关键是您必须返回Future,因为您的任务(openUrl)是异步的。 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);
  });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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