This question already has answers here:
boost::asio::read function hanging

(2个答案)


在11个月前关闭。




目前,我正在编写一个C++ Websocket客户端库,该库包装在C#库中。
我正在使用Boost Beast进行websocket连接。
现在,我要在握手完成后启动async_read,以便websocket不会断开连接。
问题是io_content阻塞了线程,因此C#程序停止执行,直到async_read超时并且io_content返回。但是我希望C#程序继续执行。
我试图在线程中执行connect函数,但是有一个问题,C#程序调用的下一个函数是写操作,并且崩溃,因为connect函数仍在连接...

library.cpp:

void OpenConnection(char* id)
{
    std::cout << "Opening new connection..." << std::endl;
    std::shared_ptr<Session> session = std::make_shared<Session>();
    session->connect();
    sessions.emplace(std::string(id), std::move(session));
}

session.cpp:

void Session::connect()
{
    resolver.async_resolve(
        "websocket_uri",
        "443",
        beast::bind_front_handler(
            &Session::on_resolve,
            shared_from_this()));
    ioc.run();
}

on_resolve,on_connect,on_handshake ...与此处相同:https://www.boost.org/doc/libs/1_70_0/libs/beast/example/websocket/client/async-ssl/websocket_client_async_ssl.cpp

除非on_handshake函数:

void Session::on_handshake(beast::error_code ec)
{
    if (ec)
        return fail(ec, "handshake");

    ws.async_read(buffer, beast::bind_front_handler(&Session::on_read, shared_from_this()));
}

和on_read函数:

void Session::on_read(beast::error_code ec, std::size_t bytes_transfered)
{
    boost::ignore_unused(bytes_transfered);

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

    std::cout << "Got message" << std::endl;
    onMessage(Message::parseMessage(beast::buffers_to_string(buffer.data())));
    ws.async_read(buffer, beast::bind_front_handler(&Session::on_read, shared_from_this()));
}

和on_write函数:

void Session::on_write(beast::error_code ec, std::size_t bytes_transfered)
{
    boost::ignore_unused(bytes_transfered);

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

    queue.erase(queue.begin());

    if (!queue.empty())
    {
        ws.async_write(net::buffer(queue.front()->toString()), beast::bind_front_handler(&Session::on_write, shared_from_this()));
    }
}

C#程序(用于测试):

[DllImport(@"/data/cpp_projects/whatsapp_web_library/build/Debug/libWhatsApp_Web_Library.so")]
public static extern void OpenConnection(string id);
[DllImport(@"/data/cpp_projects/whatsapp_web_library/build/Debug/libWhatsApp_Web_Library.so")]
public static extern void CloseConnection(string id);
[DllImport(@"/data/cpp_projects/whatsapp_web_library/build/Debug/libWhatsApp_Web_Library.so")]
public static extern void GenerateQRCode(string id);

static void Main(string[] args)
{
   string id = "test";
   OpenConnection(id);
   GenerateQRCode(id);
}

现在是我的问题,我该如何实现呢?
我已经在这个问题上停留了三天了,但我却逐渐感到绝望。

已经谢谢你了:)

最佳答案

您需要使用async_read_some而不是async_read
从助推



基本上,成功调用async_read_some可能只会读取一个字节,
也可能会填满整个缓冲区,或介于两者之间的任何位置。的
另一方面,asio::async_read函数可用于确保整个
操作完成之前,缓冲区已满。 async_write_someasio::async_write函数具有相同的关系。

More about async_read_some

这是如何使用async_read_some的好example

关于c++ - Boost asio io_content非阻塞运行,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59619047/

10-13 06:39