客户端仅会从REST服务

客户端仅会从REST服务

问题描述:

我遇到了以下这我不知道该怎样和为什么的问题线索非常有限的回应:客户端仅会从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

一旦接收到响应你的应用程序将结束。

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