I have writted a small websocket
client using boost::beast::websocket
and boost::asio::io_context
in C++
. I am having a state machine with following states:
enum class State {
GDR_PROVISING,
WEBSOCKET_HANDSHAKE,
REGISTRATION,
READY,
CLEANUP,
};
If the code is unable to set-up a connection or fails after a connection is established (possible reasons: Internet is down, Service is down, Server sends a close frame), then the state machine moves towards CLEANUP
state and should do the cleanup.
I am not sure if I can reuse the same io_context
and websocket::stream
. Currently, my io_context is only used in this single thread. I am planning to use pointers
of websockets and io_context and delete them in CLEANUP and allocate them again in GDR_PROVISING.
Can I use same websocket and io_context instance for reestablishing the connecction to the server? May be I need to call some member functions like stop
or reset
?
My READY
looks like this now:
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;
}
You can reuse
io_context
as normal. The call to run wont terminate unless there is no more work left to do when it tries to do another event loop iteration.You also can reuse the socket using
get_lowest_layer(*pWebStream_).close()
, reopening it withget_lowest_layer(*pWebStream_).open()
, and callingasync_connect
as normal. But, I think your code would be cleaner by completely resetting the object like you do.If you do want to reset the socket, I highly recommend you try using
std::optional
. It makes no heap allocations, and you don't have to worry about leaking memory.