0

我已经websocket使用boost::beast::websocketand boost::asio::io_contextin编写了一个小客户端C++。我有一个具有以下状态的状态机:

enum class State {
    GDR_PROVISING,
    WEBSOCKET_HANDSHAKE,
    REGISTRATION,
    READY,
    CLEANUP,
};

如果代码无法建立连接或建立连接后失败(可能的原因:Internet 已关闭,Service 已关闭,Server 发送关闭帧),则状态机将进入CLEANUP状态并应进行清理。

我不确定我是否可以重复使用相同的io_contextwebsocket::stream. 目前,我的 io_context 只在这个单线程中使用。我打算使用pointerswebsockets 和 io_context 并在 CLEANUP 中删除它们并在 GDR_PROVISING 中再次分配它们。

我可以使用相同的 websocket 和 io_context 实例来重新建立与服务器的连接吗?可能我需要调用一些成员函数,比如stopor reset

READY现在的样子是这样的:

    case State::READY:
    {
        // TODO: Send the Message from the vector
        {
            std::lock_guard<std::mutex> msgGaurd(msgMutex_);
            for (const auto& m: sendMsgQueue_) {
                boost::system::error_code ec;
                pWebStream_->write(boost::asio::buffer(m.toString()), ec);
            }
        }
        // Call io_context run_until to process read messages async because there is no way for non-blocking read in boost for websockets!
        pIoc_->run_until(std::chrono::steady_clock::now() + /* TODO: Add some time_point */);
        break;
    }

    case State::CLEANUP:
    {
        // TODO: Verify if we should delete the stream!
        if (pWebStream_)
            delete pWebStream_;
        if (pIoc_)
            delete pIoc_;
        pWebStream_ = nullptr;
        pIoc_ = nullptr;
        state_ = State::GDR_PROVISING;
        break;
    }
4

1 回答 1

1

您可以io_context正常重复使用。除非在尝试进行另一个事件循环迭代时没有更多工作要做,否则对 run 的调用不会终止。

您还可以使用 重用套接字get_lowest_layer(*pWebStream_).close(),使用 重新打开它get_lowest_layer(*pWebStream_).open(),然后正常调用async_connect。但是,我认为通过像您一样完全重置对象,您的代码会更干净。

如果您确实想重置套接字,我强烈建议您尝试使用std::optional. 它不进行堆分配,您不必担心内存泄漏。

于 2019-12-20T17:11:21.423 回答