2013-05-01 114 views
1

尝试在Stream服务器上使用宁静的Web服务时遇到技术问题。如何在Rikulo的Dart Stream服务器上调用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

关键是你必须返回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(); 
} 
+0

汤姆你好,谢谢你的回复!我会对你的解决方案进行测试。以下是我用来使用Acitiviti REST Web服务的代码,它引发“StreamSink已关闭”错误 – user2338071 2013-05-01 18:18:39

+0

嗨,Tom刚刚尝试过使用getUrl,仍然抛出相同的异常 – user2338071 2013-05-01 20:00:51

+0

关键是返回。请再次阅读我的答案。我澄清了它。 – 2013-05-02 01:39:27

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

我将它合并回你的问题,并修改我的答案。 – 2013-05-02 01:26:23