Reputation: 10430
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;
}
Upvotes: 0
Views: 1103
Reputation: 296
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 with get_lowest_layer(*pWebStream_).open()
, and calling async_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.
Upvotes: 1