You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Lift WS send state onto AsyncWebSocketClient; enforce one outstanding frame
AsyncWebSocketMessage is now a pure payload holder (buffer + opcode +
mask), with no per-instance send-progress fields. All in-flight-frame
state moves to a single, flat block of scalars on AsyncWebSocketClient
(_sendingControl, _sent, _maskKey, _framePayloadLen, _frameSent, _unacked)
shared uniformly between control and data frames -- there's deliberately
one set of these, not one per queue, enforcing that exactly one WS frame
may be outstanding (added to TCP but not yet acked) at a time.
Consequences of that invariant:
- A message is only popped from its queue once fully sent *and* fully
acked, so queueLen()/WS_MAX_QUEUED_MESSAGES need no changes -- a message
in progress is still physically sitting in the deque, exactly as before.
- The next queued item (control or data) is only picked up once the
in-flight frame is acked, which is also what lets control frames
interleave between fragments of a data message: the priority check runs
at every such boundary, not just at message boundaries.
- No ack-tracking FIFO is needed: since only one frame is ever outstanding,
_onAck is a single clamped subtraction instead of a per-message loop --
this also fixes a latent underflow in the old control-frame ack handling
(len -= head.len() was unclamped).
- _clearQueue(), AsyncWebSocketMessage::ack()/send(), and AwsMessageStatus
are all gone: nothing is left to sweep once queue fronts are popped
directly at the point they're known to be done.
Net effect is a memory-footprint reduction, not increase: the per-message
fields this removes cost more (spread across up to WS_MAX_QUEUED_MESSAGES
queued messages) than the one fixed block this adds to the client.
return; // waiting for the in-flight frame to be acked before starting the next one
280
+
}
389
281
390
-
if (space) {
391
-
// control frames have priority over message frames
392
-
// we can send a control frame if:
393
-
// - there is no message frame in the queue, or the first message frame is between frames (all bytes sent are acked)
394
-
// - the control frame is not finished (not sent yet)
395
-
// - there is enough space to send the control frame (control frames are small, at most 129 bytes, so we can assume that if there is space to send it, it can be sent in one go)
396
-
if (_messageQueue.empty() || _messageQueue.front().betweenFrames()) {
// this function is called when a text message is received, in order to copy the buffer and place a null terminator at the end of the buffer for easier handling of text messages.
199
190
// Returns true on success, false on failure (e.g. memory allocation failure)
0 commit comments