повысить возможность повторного использования websocket и io_context для восстановления возможности соединения

Я написал небольшой websocket клиент, использующий boost::beast::websocket а также boost::asio::io_context в C++. У меня есть конечный автомат со следующими состояниями:

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

Если код не может установить соединение или дает сбой после установления соединения (возможные причины: Интернет не работает, Служба не работает, Сервер отправляет закрывающий кадр), то конечный автомат движется к CLEANUP состояние и следует выполнить очистку.

Я не уверен, смогу ли я использовать то же самое io_context а также websocket::stream. В настоящее время мой io_context используется только в этом единственном потоке. Я планирую использоватьpointers веб-сокетов и io_context, удалите их в CLEANUP и снова разместите в GDR_PROVISING.

Могу ли я использовать один и тот же экземпляр websocket и io_context для восстановления соединения с сервером? Может быть, мне нужно вызвать некоторые функции-члены, напримерstop или 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;
    }

1 ответ

Вы можете повторно использовать io_contextкак обычно. Вызов run не будет завершен, если не останется больше работы, когда он попытается выполнить еще одну итерацию цикла событий.

Вы также можете повторно использовать сокет, используя get_lowest_layer(*pWebStream_).close(), открывая его снова с get_lowest_layer(*pWebStream_).open(), и звонит async_connectкак обычно. Но я думаю, что ваш код будет чище, если полностью сбросить объект, как вы.

Если вы действительно хотите сбросить сокет, я настоятельно рекомендую вам попробовать использовать std::optional. Он не выделяет кучи, и вам не нужно беспокоиться об утечке памяти.

Другие вопросы по тегам