Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Boost::Beast:具有websocket管道的服务器 我正在编写一个带有Boost M兽1.70和MySQL 8 C连接器的C++ WebSoC服务器。服务器将同时连接多个客户端。其特殊性在于,每个客户机将向服务器执行一行100个websocket请求。对于我的服务器,每个请求都是“cpu轻”,但服务器对每个请求执行“时间重”的sql请求_C++_Boost Asio_Boost Beast - Fatal编程技术网

Boost::Beast:具有websocket管道的服务器 我正在编写一个带有Boost M兽1.70和MySQL 8 C连接器的C++ WebSoC服务器。服务器将同时连接多个客户端。其特殊性在于,每个客户机将向服务器执行一行100个websocket请求。对于我的服务器,每个请求都是“cpu轻”,但服务器对每个请求执行“时间重”的sql请求

Boost::Beast:具有websocket管道的服务器 我正在编写一个带有Boost M兽1.70和MySQL 8 C连接器的C++ WebSoC服务器。服务器将同时连接多个客户端。其特殊性在于,每个客户机将向服务器执行一行100个websocket请求。对于我的服务器,每个请求都是“cpu轻”,但服务器对每个请求执行“时间重”的sql请求,c++,boost-asio,boost-beast,C++,Boost Asio,Boost Beast,我已经用websocket\u server\u coro.cpp示例启动了我的服务器。服务器步骤包括: 1) websocket阅读器 2) sql请求 3) 网匣 问题是,对于给定的用户,服务器在步骤2被“锁定”,并且在该步骤和步骤3完成之前无法读取。因此,100个请求被顺序地解决。这对于我的用例来说太慢了 我已经读到boost beast不可能实现非阻塞读/写。然而,我现在要做的是在一个协同程序中执行异步读取和异步写入 void ServerCoro::accept(websocket::

我已经用websocket\u server\u coro.cpp示例启动了我的服务器。服务器步骤包括:

1) websocket阅读器

2) sql请求

3) 网匣

问题是,对于给定的用户,服务器在步骤2被“锁定”,并且在该步骤和步骤3完成之前无法读取。因此,100个请求被顺序地解决。这对于我的用例来说太慢了

我已经读到boost beast不可能实现非阻塞读/写。然而,我现在要做的是在一个协同程序中执行异步读取和异步写入

void ServerCoro::accept(websocket::stream<beast::tcp_stream> &ws) {
    beast::error_code ec;

    ws.set_option(websocket::stream_base::timeout::suggested(beast::role_type::server));

    ws.set_option(websocket::stream_base::decorator([](websocket::response_type &res) {
                res.set(http::field::server, std::string(BOOST_BEAST_VERSION_STRING) + " websocket-Server-coro");
            }));

    ws.async_accept(yield[ec]);
    if (ec) return fail(ec, "accept");

    while (!_bStop) {
        beast::flat_buffer buffer;
        ws.async_read(buffer, yield[ec]);

        if (ec == websocket::error::closed) {
            std::cout << "=> get closed" << std::endl;
            return;
        }

        if (ec) return fail(ec, "read");

        auto buffer_str = new std::string(boost::beast::buffers_to_string(buffer.cdata()));
        net::post([&, buffer_str] {

            // sql async request such as :
            // while (status == (mysql_real_query_nonblocking(this->con, sqlRequest.c_str(), sqlRequest.size()))) {
            //    ioc.poll_one(ec);
            // }
            // more sql ...

            ws.async_write(net::buffer(worker->getResponse()), yield[ec]); // this line is throwing void boost::coroutines::detail::pull_coroutine_impl<void>::pull(): Assertion `! is_running()' failed.
            if (ec) return fail(ec, "write");

        });
    }
}
void服务器coro::accept(websocket::stream&ws){
beast::错误代码ec;
ws.set_选项(websocket::stream_base::timeout::suggered(beast::role_type::server));
ws.set_选项(websocket::stream_base::decorator([](websocket::response_type&res){
res.set(http::field::server,std::string(BOOST\u BEAST\u VERSION\u string)+“websocket服务器coro”);
}));
异步接受(收益率[ec]);
如果(ec)返回失败(ec,“接受”);
while(!\u bStop){
beast::flat_缓冲区;
异步读取(缓冲区,收益率[ec]);
如果(ec==websocket::error::closed){
std::cout getResponse()),yield[ec]);//此行正在抛出void boost::coroutines::detail::pull\u coroutine\u impl::pull():断言“!is\u running()”失败。
如果(ec)返回失败(ec,“写入”);
});
}
}
问题是具有async_write的行抛出错误:

void boost::coroutines::detail::pull\u coroutine\u impl::pull():断言`!正在运行()失败

如果将此行替换为sync_write,则它可以工作,但对于给定用户,服务器仍保持顺序。 我尝试在单线程服务器上执行此代码。我还尝试使用相同的串进行异步读取和异步写入。仍然存在断言错误

使用boost beast for websocket,这样的服务器不可能吗?
谢谢。

根据Vinnie Falco的建议,我以“websocket聊天”和“异步服务器”为例重写了代码。以下是代码的最终工作结果:

void Session::on_read(beast::error_code ec,std::size_t bytes_transfer)
{
boost::忽略未使用的字节(传输的字节);
if(ec==websocket::error::closed)return;//这表示会话已关闭
如果(ec)返回失败(ec,“读取”);
net::post([&,that=shared\u from_this(),ss=std::make\u shared(std::move(boost::beast::buffers\u to_string(_buffer.cdata())))]{
/*在这里调用ioc.poll_one(ec)的Sql东西,对我来说,Sql响应进入下面使用的worker.getResponse()内部*/
net::dispatch(_wstrand,[&,that=shared_from_this(),sss=std::make_shared(worker.getResponse())]{
异步写入(sss);
});
});
_buffer.consume(_buffer.size());//我们从缓冲区中删除刚刚读取的内容
do_read();//进行另一次读取
}
无效会话::异步写入(const std::共享会话和消息){
_写消息。推回(消息);
如果(_writeMessages.size()>1){

BOOST_LOG_Trial(警告)您是否尝试将SQL工作分派到单独的线程池,然后将结果发布回web套接字连接的链?这应该允许您同时执行SQL操作。您需要实现传出消息队列,代码可以在“websocket chat”中找到Beast示例程序。它运行良好。我使用了“websocket聊天”和“async server”的示例。我将sql代码放在没有串的net::post中,websocket在串上写/读(带有异步写入的队列)。感谢Vinnie Falco的回复和您在boost beast上的工作。这看起来很棒,但仍然可以改进。由于您使用的是boost 1.70,您可以将链放在NextLayer对象上,并在构建websocket时对其进行初始化。然后,所有异步websocket操作都将自动使用该链不需要在呼叫站点使用bind_executor。文档中介绍了这一点。