повысить возможность повторного использования 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
. Он не выделяет кучи, и вам не нужно беспокоиться об утечке памяти.