【问题标题】:http_listener cpprestsdk how to handle multiple POST requestshttp_listener cpprestsdk 如何处理多个 POST 请求
【发布时间】:2017-05-04 22:21:14
【问题描述】:

我用 casablanca cpprestskd 开发了一个客户端服务器应用程序。 客户端每 5 分钟通过 POST 方法从其任务管理器(进程、cpu 使用情况等)发送信息到服务器。

该项目应该能够管理大约 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;

}

基本上它可以工作,但如果我尝试同时从适当的客户发送信息,有时它会工作,有时它不起作用。 显然,当我打开“uploaded.txt”流文件时会出现问题。 问题:

1) CASABLANCA http_listener 是真正的多任务处理吗?它能够处理多少任务? 2)我没有在文档中找到类似于我的斧头示例,唯一接近我的是“Casalence120”项目,但他使用 Concurrency::Reader_writer_lock 类(它似乎是互斥锁方法)。 我该怎么做才能管理多个 POST? 3)是否可以在开始打开uploaded.txt之前阅读一些客户端信息? 我可以直接使用客户端名称打开输出文件流。 4)如果我通过对upload.txt 文件的互斥锁访问,服务器变为顺序,我认为这不是使用cpprestsdk 的好方法。 我仍在接近 cpprestskd,因此任何建议都会有所帮助。

【问题讨论】:

    标签: c++11 visual-studio-2013 client-server httplistener cpprest-sdk


    【解决方案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 极大地简化了代码的可读性。 基本上每次你“co_await”一个函数时,编译器都会“继续”重构代码,避免冻结执行函数本身的线程的惩罚。这样,您就摆脱了“.then”语句。
    4. 文件问题与 REST sdk 不同。同时访问文件系统是你应该在一个单独的项目中测试的东西。您可能可以缓存第一次读取并与其他线程共享内容,而不是每次都访问磁盘。

    【讨论】:

    • 当我打开“uploaded.txt”流文件时,我不需要与其他客户端共享信息,它只是一个临时文件,我需要读取客户端登录名和密码以及一些我需要的东西将其复制到与客户端同名的文件中。有没有机会每次都打开一个不同名字的流文件?我可以这样解决!
    • 我对你最后的要求感到困惑。当然有机会用不同的名称打开流文件,这取决于您了解异步调用的流程。可能代码会通过使用协程来简化。调试时使用“then”的延续可能难以理解。 (我明白这个问题了吗?)
    • 我解决了为每个客户端打开一个具有不同名称的流文件。我强调使用 Jmeter 进行测试,Server 能够管理多个客户端请求。现在我必须使用功能单元测试完成测试,之后我将尝试使用协程更改 .then 方法。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-02-13
    • 1970-01-01
    • 2012-04-02
    • 1970-01-01
    • 1970-01-01
    • 2022-01-21
    • 2020-03-29
    相关资源
    最近更新 更多