1

我开发了一个客户端服务器应用程序与卡萨布兰卡cpprestskd。 客户端每隔5分钟通过POST方法将任务管理器(进程,CPU使用率等)的信息发送到服务器。http_listener cpprestsdk如何处理多个POST请求

该项目应该能够管理大约100个客户端。 每当服务器收到一个POST请求时,他会打开一个输出文件流(“uploaded.txt”),从客户端(登录名,密码)中提取一些初始信息,管理这些信息,将所有信息保存在同名文件客户端(例如:client1.txt,client2.txt),最后用状态码回复客户端。 这基本上是从服务器端我的POST处理代码:

void Server::handle_post(http_request request) 
{ 

auto fileBuffer = 
    std::make_shared<Concurrency::streams::basic_ostream<uint8_t>>(); 
try 
{ 
    auto stream = concurrency::streams::fstream::open_ostream(
     U("uploaded.txt"), 
     std::ios_base::out | std::ios_base::binary).then([request, fileBuffer](pplx::task<Concurrency::streams::basic_ostream<unsigned char>> Previous_task) 
    { 

     *fileBuffer = Previous_task.get(); 
     try 
     { 
      request.body().read_to_end(fileBuffer->streambuf()).get(); 
     } 
     catch (const exception&) 
     { 
      wcout << L"<exception>" << std::endl; 
      //return pplx::task_from_result(); 
     } 
     //Previous_task.get().close(); 

    }).then([=](pplx::task<void> Previous_task) 
    { 


     fileBuffer->close(); 
     //Previous_task.get(); 
    }).then([](task<void> previousTask) 
    { 
     // This continuation is run because it is value-based. 
     try 
     { 
      // The call to task::get rethrows the exception. 

      previousTask.get(); 
     } 
     catch (const exception& e) 
     { 
      wcout << e.what() << endl; 
     } 
    }); 
    //stream.get().close(); 
} 
catch (const exception& e) 
{ 
    wcout << e.what() << endl; 
} 


ManageClient(); 

request.reply(status_codes::OK, U("Hello, World!")).then([](pplx::task<void> t) { handle_error(t); }); 
return; 

} 

基本上它的工作原理,但如果我尝试在同一时间,由于从客户端发送信息,有时它的工作原理有时doen't工作。 很明显,如果当我打开“uploaded.txt”流文件的问题。 问题:

1)CASABLANCA http_listener是真正的多任务吗?它能够处理多少任务? 2)我没有发现类似于我的文档ax例子,唯一接近我的是“Casalence120”项目,但他使用了Concurrency :: Reader_writer_lock类(它似乎是一个互斥方法)。 我能做些什么来管理多个POST? 3)在开始upload.txt之前,是否可以阅读一些客户信息? 我可以用客户端的名字直接打开输出文件流。 4)如果我通过上传锁定通过互斥体访问upload.txt文件,服务器成为顺序,我认为这不是一个好方法使用cpprestsdk。 我还在接近cpprestskd,所以任何建议都会有所帮助。

回答

1
  1. 是,其余的SDK程序在不同的线程
  2. 我确认有没有使用监听器的例子很多每个请求。 使用听众的官方示例可以在这里找到: https://github.com/Microsoft/cpprestsdk/blob/master/Release/samples/CasaLens/casalens.cpp
  3. 我看到你正在使用VS.我强烈建议迁移到VC++ 2015或更好的VC++ 2017,因为最新的编译器支持协同例程。 使用co_await大大简化了代码的可读性。 几乎每次你'co_await'一个函数,编译器都会在“继续”中重构代码,避免了冻结执行函数本身的线程的代价。这样,你就摆脱了“那么”的陈述。
  4. 文件问题与REST sdk不同。同时访问文件系统是您应该在单独项目中测试的内容。您可以缓存第一次读取内容并与其他线程共享内容,而不是每次访问磁盘。
+0

当我打开“uploaded.txt”流文件时,我不需要与其他客户端共享信息,它只是一个临时文件,我需要读取客户端登录名和密码,以及某些东西后我需要将其复制在一个与客户端名称相同的文件中。是否有机会每次打开一个不同名称的流文件?我可以这样解决! – kenhero

+0

我很困惑你最后的要求。当然,有机会以不同的名称打开流文件,只是了解异步调用的流程。 可能通过使用协程来简化代码。调试时,使用“then”的延续可能难以理解。 (我理解这个问题吗?) – raf

+1

我解决了为每个客户打开一个不同名称的流文件。我强调Jmeter和Server的测试能够管理多个客户端请求。 现在我必须用功能单元测试完成测试,之后我会尝试更改。然后使用协程来修改。谢谢 – kenhero