sendWithAck method

Future<void> sendWithAck(
  1. WebSocketMessage message
)

Sends message and returns a Future that completes when the server acknowledges it, or throws TimeoutException after retries are exhausted.

The __ack_id__ is embedded directly in the wire payload so the server can read it without any custom framing. For Map payloads the key is merged at the top level; for all other payloads the data is wrapped as {"__ack_id__": id, "payload": data}.

Implementation

Future<void> sendWithAck(WebSocketMessage message) {
  if (_disposed) return Future.error(StateError('AckManager disposed'));

  final id = _generateId();
  final meta = Map<String, dynamic>.from(message.metadata ?? {});
  meta[_kAckIdKey] = id;

  // Embed __ack_id__ into the wire payload so the server receives it.
  final dynamic wireData;
  final data = message.data;
  if (data is Map<String, dynamic>) {
    wireData = {...data, _kAckIdKey: id};
  } else {
    wireData = {_kAckIdKey: id, 'payload': data};
  }

  final wrapped = WebSocketMessage(
    data: wireData,
    timestamp: message.timestamp,
    type: 'json',
    metadata: meta,
  );

  final pending = _PendingAck(id: id, message: wrapped);
  _pending[id] = pending;

  _sender(wrapped).then((_) {
    pending.scheduleTimeout(timeout, _onTimeout);
  }).catchError((e) {
    _pending.remove(id);
    pending.fail(e);
  });

  return pending.future;
}