I recently ran into a problem with trying to broadcast to an open WebSocket using the SendAsync method, receiving an InvalidOperationException with the message "A send operation is already in progress"
Digging through the source code for the WebSocket class, a busy state is tracked internally:
internal ChannelState _sendState;
// Represents the state of a single channel; send and receive have their own states
internal enum ChannelState {
Ready, // this channel is available for transmitting new frames
Busy, // the channel is already busy transmitting frames
Closed // this channel has been closed
}
Ideally, if I'm about to broadcast an update to a WebSocket connection, I'd like to know ahead of time that it's busy and perform some other handling (e.g. queue the message).
It seems odd that this state is marked as internal -- were it a public property I could simply check for
context.WebSocket.SendState == ChannelState.Ready
What is the correct pattern to SendAsync on a WebSocket that would prevent throwing this exception?
I'm loath to hack access to that property through reflection.
Edit to clarify:
The WebSocket.State property will not help this situation. The property uses this enumeration:
public enum WebSocketState
{
None,
Connecting,
Open,
CloseSent,
CloseReceived,
Closed,
Aborted
}
Once the socket connection has been opened, this statement will evaluate to "true" regardless of whether or not it is busy sending:
context.WebSocket.State == WebSocketState.Open