sendRequest static method

Future<OBPFrame?> sendRequest(
  1. P2PStream stream,
  2. OBPFrame request, {
  3. Duration timeout = defaultTimeout,
  4. int maxRetries = maxRetries,
  5. String context = 'unknown',
})

Send a request frame and wait for response

Handles retries, timeouts, and acknowledgments automatically.

Implementation

static Future<OBPFrame?> sendRequest(
  core_p2p_stream.P2PStream stream,
  OBPFrame request, {
  Duration timeout = defaultTimeout,
  int maxRetries = maxRetries,
  String context = 'unknown',
}) async {
  for (int attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      _logger.fine('[$context] Sending request (attempt $attempt/$maxRetries): ${request.type}');

      // Send request frame
      await _writeFrame(stream, request, timeout: timeout, context: context);

      // Wait for response
      final response = await _readFrame(stream, timeout: timeout, context: context);

      if (response == null) {
        _logger.warning('[$context] No response received for ${request.type} (attempt $attempt)');
        if (attempt < maxRetries) continue;
        return null;
      }

      // Check for error response
      if (response.type == OBPMessageType.error) {
        final errorMsg = utf8.decode(response.payload);
        _logger.warning('[$context] Received error response: $errorMsg');
        return response; // Return error response for caller to handle
      }

      _logger.fine('[$context] Received response: ${response.type}');
      return response;

    } catch (e) {
      _logger.warning('[$context] Request attempt $attempt failed: $e');
      if (attempt >= maxRetries) {
        _logger.severe('[$context] All request attempts failed for ${request.type}');
        rethrow;
      }

      // Wait before retry
      await Future.delayed(Duration(milliseconds: 100 * attempt));
    }
  }

  return null;
}