handle method

  1. @override
Future<void> handle(
  1. P2PStream stream
)
override

Handle calls Negotiate to determine which protocol handler to use for an inbound stream, then invokes the protocol handler function, passing it the protocol ID and the stream. Returns an error if negotiation fails.

Implementation

@override
Future<void> handle(P2PStream<dynamic> stream) async {
  late final ProtocolID proto;
  late final HandlerFunc handler;
  try {
    final result = await negotiate(stream);
    proto = result.$1;
    handler = result.$2;
  } catch (e) {
    // Clean up any leftover bytes on negotiation failure
    _leftoverMap.remove(stream.id());
    rethrow;
  }

  // After negotiation, inject any leftover bytes back into the stream.
  // This handles the case where Go sends protocol negotiation + application data
  // in the same TCP segment.
  _injectLeftover(stream);

  // Ensure the stream is valid before proceeding
  if (stream.isClosed) {
    _log.warning(
        '[multistreamMuxer - handle] Stream for protocol $proto was closed during or immediately after negotiation. Aborting handler call.');
    return;
  }

  try {
    _log.fine(
        '[multistreamMuxer - handle] Protocol $proto negotiated. Attempting to set protocol on stream scope and stream itself.');
    await stream.scope().setProtocol(proto);
    await stream.setProtocol(proto);
    _log.fine(
        '[multistreamMuxer - handle] Successfully set protocol $proto on stream scope and stream. Proceeding to call handler.');
  } catch (e, s) {
    _log.severe(
        '[multistreamMuxer - handle] CRITICAL: Error occurred while setting protocol $proto on stream scope/stream: $e\n$s. Resetting stream and not calling handler.');
    await stream.reset();
    rethrow;
  }

  // Only call the handler if setProtocol was successful
  return handler(proto, stream);
}