2017-08-15 123 views
0

我遇到了以下這我不知道該怎樣和爲什麼的問題線索非常有限的迴應:客戶端僅會從REST服務

我已經用C寫一個WebService ++。我還爲應該測試響應的客戶端使用了一個示例。

client.cpp

#include <memory> 
#include <future> 
#include <cstdio> 
#include <cstdlib> 
#include <restbed> 

using namespace std; 
using namespace restbed; 

void print(const shared_ptr<Response>& response) 
{ 
    fprintf(stderr, "*** Response ***\n"); 
    fprintf(stderr, "Status Code: %i\n", response->get_status_code()); 
    fprintf(stderr, "Status Message: %s\n", response->get_status_message().data()); 
    fprintf(stderr, "HTTP Version: %.1f\n", response->get_version()); 
    fprintf(stderr, "HTTP Protocol: %s\n", response->get_protocol().data()); 

    for (const auto header : response->get_headers()) 
    { 
     fprintf(stderr, "Header '%s' > '%s'\n", header.first.data(), header.second.data()); 
    } 

    auto length = response->get_header("Content-Length", 0); 

    Http::fetch(length, response); 

    fprintf(stderr, "Body:   %.*s...\n\n", length, response->get_body().data()); 
} 

int main(){ 
    auto request = make_shared<Request>(
      Uri("http://localhost:3030/apps/17?start_date=2017-02-01&end_date=2017-01-31&kpis=foo,bar")); 
    request->set_header("Accept", "application/json"); 
    request->set_header("Host", "localhost"); 

    auto response = Http::sync(request); 
    print(response); 

    auto future = Http::async(request, [](const shared_ptr<Request>, const shared_ptr<Response> response){ 
     fprintf(stderr, "Printing async response\n"); 
     print(response); 
    }); 

    future.wait(); 

    return EXIT_SUCCESS; 
} 

而我的服務流中的塊的響應(或應該流以塊的響應) 首先,流請求的參數,如日期,結束日期和KPI 。其次,請求的數據是流式傳輸的。

這裏是stream_result_parameter功能:

void stream_result_parameter(std::shared_ptr<restbed::Session> session, const Parameter params, 
          const std::string endpoint, const std::string mime_type) 
{ 
    std::stringstream  stream; 

    if(mime_type.compare("application/json") == 0) 
    { 
     std::vector<std::string> kpis = params.get_kpis(); 
     stream << "\n{\n" 
       << "\"result_parameter\":{\n" 
       << "\"App\":" << params.get_app_id() << ",\n" 
       << "\"start_date\":" << params.get_start_date() << ",\n" 
       << "\"end_date\":" << params.get_end_date() << ",\n" 
       << "\"Kpis\":["; 

     for(std::vector<std::string>::iterator kpi = kpis.begin(); kpi != kpis.end(); ++kpi) 
     { 
      if(kpi == kpis.end()-1) 
      { 
       stream << *kpi << "]\n},"; 
      } 
      else 
      { 
       stream << *kpi << ","; 
      } 

     } 

    } 
    else 
    { 
     if(endpoint.compare("app") == 0) 
     { 
      stream << "Called App Endpoint App: " 
        << std::to_string(params.get_app_id()) 
        << "\r\nStart Date: " 
        << params.get_start_date() 
        << "\r\nEnd Date: " 
        << params.get_end_date() 
        <<"\n"; 

     } 
     else 
     { 
      stream << "Called Cohorts Endpoint App: " 
        << std::to_string(params.get_app_id()) 
        << "\r\nStart Date: " 
        << params.get_start_date() 
        << "\r\nEnd Date: " 
        << params.get_end_date() 
        <<"\n"; 

     } 
    } 
    session->yield(200, "\r"+stream.str()+"\r", 
        { { "Content-Length", std::to_string(stream.str().length())}, 
        { "Content-Type", mime_type }, 
        { "Connection", "keep-alive" } }); 
}  

現在,經過我添加了內容長度到它那裏它只是停止並關閉客戶端和他(服務)之間的對話我的問題發生。 curl給了我下面的錯誤

* Trying ::1... 
* TCP_NODELAY set 
* Connected to localhost (::1) port 3030 (#0) 
> GET /apps/17?start_date=2017-02-01&end_date=2017-01-31&kpis=foo,bar HTTP/1.1 
> Host: localhost:3030 
> User-Agent: curl/7.54.0 
> Accept:text/csv 
> 
< HTTP/1.1 200 OK 
< Connection: keep-alive 
< Content-Length: 94 
< Content-Type: text/csv 
< 
* Excess found in a non pipelined read: excess = 2, size = 94, maxdownload = 94, bytecount = 0 
Called App Endpoint App: 17 
Start Date: Wed. February 1 2017 
* Connection #0 to host localhost left intact 
End Date: Tue. January 31 2017 

是否過剩有什麼關係呢?

最後,我想告訴你我的測試客戶端和curl的輸出,如果我把內容長度帶走

client.cpp輸出:

*** Response *** 
Status Code: 200 
Status Message: OK 
HTTP Version: 1.1 
HTTP Protocol: HTTP 
Header 'Connection' > 'keep-alive' 
Header 'Content-Type' > 'application/json' 
Body:   ... 

Printing async response 
*** Response *** 
Status Code: 200 
Status Message: OK 
HTTP Version: 1.1 
HTTP Protocol: HTTP 
Header 'Connection' > 'keep-alive' 
Header 'Content-Length' > '64' 
Header 'Content-Type' > 'application/json' 
Body:   
"result_set":{ 
"i":1, 
"j values": [ 
{"j":1,"kpi_values":[1,1]}... 

curl給我我需要的一切:

* Trying ::1... 
* TCP_NODELAY set 
* Connected to localhost (::1) port 3030 (#0) 
> GET /apps/17?start_date=2017-02-01&end_date=2017-01-31&kpis=foo,bar HTTP/1.1 
> Host: localhost:3030 
> User-Agent: curl/7.54.0 
> Accept:text/csv 
> 
< HTTP/1.1 200 OK 
< Connection: keep-alive 
< Content-Type: text/csv 
* no chunk, no close, no size. Assume close to signal end 
< 
Called App Endpoint App: 17 
Start Date: Wed. February 1 2017 
End Date: Tue. January 31 2017 
1,1,1,1 
1,2,1,2 
1,3,1,3 
1,4,1,4 
1,5,1,0 
1,6,1,1 
1,7,1,2 
1,8,1,3 
1,9,1,4 
1,10,1,0 
2,1,2,1 
2,2,2,2 
2,3,2,3 
2,4,2,4 
2,5,2,0 
2,6,2,1 
2,7,2,2 
2,8,2,3 
2,9,2,4 
2,10,2,0 

(請注意,我不想複製17400線,使它就是完整的一部分,正確的輸出)

也許我違反了一些規則或缺少別的東西,但我無法想到它。在此先感謝

UPDATE:

一次我佔"/r"秒,但仍然響應發送並沒有更多的塊可以按照過剩的消息了:

* Trying ::1... 
* TCP_NODELAY set 
* Connected to localhost (::1) port 3030 (#0) 
> GET /apps/17?start_date=2017-02-01&end_date=2017-01-31&kpis=foo,bar HTTP/1.1 
> Host: localhost:3030 
> User-Agent: curl/7.54.0 
> Accept:text/csv 
> 
< HTTP/1.1 200 OK 
< Connection: keep-alive 
< Content-Length: 96 
< Content-Type: text/csv 
< 
Called App Endpoint App: 17 
Start Date: Wed. February 1 2017 
End Date: Tue. January 31 2017 
* Connection #0 to host localhost left intact 
+1

這是可疑的:'「\ r」+ stream.str()+「\ r」'。特別是在'std :: to_string(stream.str()。length())'之後。你確定你添加的兩個'\ r'字符不應該被計入內容長度嗎?這將解釋'2'的過量。 – spectras

+0

我希望這會是,即使消除他們也不會做伎倆,雖然多餘的消息消失! –

+0

'長度'的類型是什麼? ''%。* s「'不應該使用非int作爲寬度說明符。非相關的提示,你可以使用'std :: prev(kpis.end())'而不是'kpis.end() - 1',所以你知道獨立於容器/迭代器類型,它會做右事情。 – jweyrich

回答

0

一旦接收到響應你的應用程序將結束。

auto future = Http::async(request, [](const shared_ptr<Request>, const shared_ptr<Response> response){ 
    fprintf(stderr, "Printing async response\n"); 
    print(response); 
}); 

future.wait(); 

請參閱最後的結果github上issue

+0

好吧,但看看我發佈的更新,這是'curl'而不是你的client.cpp 我不想關閉會話,我只想知道session-> yield是否可以用於流傳輸http響應。 –

+0

是的,它可以用來傳輸HTTP響應。並廣泛用於商業環境。 – Corvusoft

+0

對不起,你問你能從客戶端流嗎? – Corvusoft