在 Boost ASIO 服务器中处理生命周期

Handling lifetime in a Boost ASIO server

我正在尝试使用 beast websockets 基本上重新创建 boost 异步日间服务器示例。

rubymud_server class 的 handle_accept 方法内部调用 new_connection->handshake()。一旦函数体退出,我相信我的 new_connection 会丢失所有引用计数并死掉。如果是这样的话,这东西返回响应是不是运气好? ws_connectionws_ 成员上的 ws_.async_acceptws_.async_write 是否在 shared_ptr 被销毁之前完成?

class ws_connection : public boost::enable_shared_from_this<ws_connection> {
public:
    typedef boost::shared_ptr<ws_connection> pointer;

    static pointer create(boost::asio::io_service& io_service)
    {
        return pointer(new ws_connection(io_service));
    }

    void handshake()
    {
        ws_.async_accept(boost::bind(&ws_connection::handle_accept, shared_from_this()));
    }

    tcp::socket& socket()
    {
        return ws_.next_layer();
    }

private:
    ws_connection(boost::asio::io_service& io_service) : ws_(io_service)
    {
        response_ << "Hello from obsidian-server!";
    }

    void handle_accept() {
        ws_.async_write(response_.data(), boost::bind(&ws_connection::handle_write, shared_from_this()));
    }

    void handle_write() {
        std::cout << "handle_write" << std::endl;
    }

    beast::websocket::stream<boost::asio::ip::tcp::socket> ws_;
    beast::streambuf response_;
};

class rubymud_server {
public:
    using error_code = boost::system::error_code;

    rubymud_server(boost::asio::io_service& io_service) : acceptor_(io_service, tcp::endpoint(tcp::v4(), 33435))
    {
        start_accept();
    }

private:
    void start_accept()
    {
        ws_connection::pointer new_connection = ws_connection::create(acceptor_.get_io_service());
        acceptor_.async_accept(new_connection->socket(),
                boost::bind(
                        &rubymud_server::handle_accept,
                        this,
                        new_connection,
                        boost::asio::placeholders::error
                )
        );
    }

    void handle_accept(ws_connection::pointer new_connection, const error_code& error) {
        new_connection->handshake();
        start_accept();
    }

    tcp::acceptor acceptor_;
};

int main(int argc, char* argv[]) {
    boost::asio::io_service io_service;
    rubymud_server server(io_service);
    io_service.run();
}

我不确定我是否理解这个问题,但我会看看我能做些什么。我感觉你不明白io_service是什么,所以我要说的是:io_service是一个异步函数的队列。每个异步调用都在 io_service 的队列中。

当您构建 class 时,io_service 会传递给它。 假设 io_service 不会在 class 之前被销毁(这很重要),您的下一个要求是 class 的对象一直存活到 io_service 队列为空。为确保这一点,您 post 函数指向 io_service,指针为 shared_from_this()。意思是,只要 io_service 中还有一个 shared_ptr 的实例存在,你的 class 就永远不会被销毁,因为 shared_ptr 计数器永远不会为零。

再说一次:所有这些都假定 io_service 将一直存在,直到 class 的对象被销毁。一旦队列为空,this 的共享指针将自动消失,您的 shared_ptr 可以安全销毁。

这是否回答了您的问题?