1

나는 casablanca cpprestskd를 사용하여 클라이언트 서버 응용 프로그램을 개발했습니다. 5 분마다 클라이언트는 자신의 작업 관리자 (프로세스, CPU 사용 등)의 정보를 POST 방법을 통해 서버로 보냅니다.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) uploaded.txt를 열기 전에 일부 클라이언트 정보를 읽을 수 있습니까? 출력 파일 스트림을 클라이언트의 이름으로 직접 열 수 있습니다. 4) uploaded.txt 파일에서 뮤텍스를 통해 액세스를 잠그면 서버가 순차적으로되고 이것이 cpprestsdk를 사용하는 좋은 방법이 아닌 것 같습니다. 아직 제안이 도움이 될 수 있도록 cpprestskd에 접근 중입니다.

답변

1
  1. 예, REST SDK를 프로세스를 다른 스레드 내가 리스너를 사용하여 많은 예제가 아닌 확인
  2. 에 대한 모든 요청. 수신기를 사용하는 공식 샘플은 여기에서 찾을 수 있습니다. https://github.com/Microsoft/cpprestsdk/blob/master/Release/samples/CasaLens/casalens.cpp
  3. VS에서 작업하는 것을 볼 수 있습니다. 나는 가장 최근의 컴파일러가 공동 루틴을 지원하기 때문에 VC++ 2015 또는 VC++ 2017로 옮길 것을 강력히 제안한다. co_await을 사용하면 코드 가독성이 크게 향상됩니다. 함수를 실행할 때마다 실질적으로 컴파일러는 함수 자체를 실행하는 스레드를 고정시키지 않는 페널티를 피하면서 코드를 "계속"리펙토링합니다. 이렇게하면 ".then"문장을 제거 할 수 있습니다.
  4. 파일 문제는 REST SDK와는 다른 이야기입니다. 파일 시스템에 동시에 액세스하는 것은 별도의 프로젝트에서 테스트해야하는 사항입니다. 매회 디스크에 액세스하지 않고 첫 번째 읽기를 캐싱하고 다른 스레드와 콘텐츠를 공유 할 수 있습니다.
+0

"uploaded.txt"스트림 파일을 열 때 다른 클라이언트와 정보를 공유 할 필요가 없습니다. 클라이언트 로그인과 암호를 읽고 필요한 일부 항목을 복사해야하는 임시 파일 일뿐입니다. 클라이언트 이름이 같은 파일 매번 다른 이름으로 스트림 파일을 열 수 있습니까? 그런 식으로 해결할 수 있습니다! – kenhero

+0

마지막 요청으로 혼란 스럽습니다. 물론 스트림 파일을 다른 이름으로 열 수있는 기회가 있습니다. 비동기 호출의 흐름을 이해하는 것은 당신에게 달려 있습니다. 아마도 코드는 coroutines를 사용하여 단순화 될 것입니다. "then"을 사용하는 연속은 디버깅 할 때 이해하기 어려울 수 있습니다. (질문을 이해 했습니까?) – raf

+1

모든 클라이언트에 대해 서로 다른 이름의 스트림 파일을 열어 보았습니다.나는 Jmeter로 테스트를 강조했고 Server는 여러 클라이언트 요청을 관리 할 수 ​​있습니다. 이제 기능 단위 테스트로 테스트를 마쳐야합니다. 그 후에는 코 루틴으로 메소드를 변경하려고 시도 할 것입니다. 감사 – kenhero