2013-05-01 137 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