I am sending data on a boost::beast::websocket
I would like to send the data synchronously, so am trying to decide if I should use write
or write_some
.
From this SO answer (which is about asio
rather than beast
specifically, but I assume(!) the same rules apply?) I understand that write
will block until the entire message is confirmed sent, whereas write_some
may return early, and will return the number of bytes sent which may not be all the bytes which were requested be sent.
In my particular use-case I am using a single thread, and the write is done from within this thread's context (ie: from inside a callback issued after entering io_context.run()
)
Since I don't want to block the caller for some indeterminate amount of time, I want to avoid using write
if there is a more elegant solution.
So if I then turn to async_write
, I am uncertain what I should do if the number of bytes is less than the number of bytes I requested be sent?
How I would normally handle this with standard tcp sockets is use non-blocking mode, and when I get back EWOULDBLOCK
, enqueue the data and carry on. When the socket becomes writeable again, only then complete the write (much akin to an asio async_write
). Since non-blocking is not supported in beast, I'm wondering what the analogous approach is?
Presumably I need to perform some additional write operation to ensure the rest of the bytes are sent in due course?
The beast docs say
Callers are responsible for synchronizing operations on the socket using an implicit or explicit strand, as per the Asio documentation. The websocket stream asynchronous interface supports one of each of the following operations to be active at the same time:
async_read or async_read_some async_write or async_write_some async_ping or async_pong async_close
Is it ok to start an async write of the remaining bytes, so long as I ensure that a new synchronous write/write_some isn't started before the outstanding async write has completed?
If I cannot start an async write to complete the send of the remaining bytes, how is one supposed to handle a synchronous write_some
which doesn't completely send all bytes?
As to why I don't just use async_write
always, I have additional slow processing to do after the attempt to write, such as logging etc. Since I am using a single thread, and the call to async_write
happens within that thread, the write will only occur after I return control to the event loop.
So what I'd like to do is attempt to write synchronously (which will work in 90% of the cases) so the data is sent, and then perform my slow tasks which would otherwise delay the write. In the 10% of cases where a sync write
doesn't complete immediately, then an alternative async_write
operation should be employed - but only in the fallback situation.
Possibly related: I see that write_some
has a flag fin
, which should be set to true if this is the last part of the message.
I am only ever attempting to write complete messages, so should I always use true for this?