Like a regular asio socket, a
stream is not thread safe. Callers
are responsible for synchronizing operations on the socket using an implicit
or explicit strand, as per the Asio documentation. The asynchronous interface
supports one active read and one active write simultaneously. Undefined behavior
results if two or more reads or two or more writes are attempted concurrently.
Caller initiated WebSocket ping, pong, and close operations each count as
an active write.
The implementation uses composed asynchronous operations internally; a high level read can cause both reads and writes to take place on the underlying stream. This behavior is transparent to callers.