【问题标题】:Boost asio io_content run non-blocking [duplicate]Boost asio io_content 运行非阻塞[重复]
【发布时间】:2020-01-06 21:12:33
【问题描述】:

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

库.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);
}

现在是我的问题,我该如何实施?
我已经在这个问题上卡了 3 天了,慢慢地绝望了。

已经谢谢了:)

【问题讨论】:

标签: c++ boost boost-asio blocking boost-beast


【解决方案1】:

您需要使用async_read_some 而不是async_read

来自提升

async_read_some 函数用于从流套接字异步读取数据。函数调用总是立即返回。

读取操作可能不会读取所有请求的字节数。 如果需要确保 在异步操作之前读取请求的数据量 完成。

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

More about async_read_some

这里有一个很好的exampleasync_read_some的使用方法

【讨论】:

    猜你喜欢
    • 2013-06-23
    • 1970-01-01
    • 1970-01-01
    • 2013-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多