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