newStream method

  1. @override
Future<P2PStream> newStream(
  1. Context context,
  2. PeerId peerId
)
override

Returns a new stream to given peer p. If there is no connection to p, attempts to create one.

Implementation

@override
Future<P2PStream> newStream(Context context, PeerId peerId) async {
  _logger.warning('Swarm.newStream: Entered for peer ${peerId.toString()}. Context HashCode: ${context.hashCode}');
  // Check if we're closed
  if (_isClosed) {
    _logger.warning('Swarm.newStream: Swarm is closed for peer ${peerId.toString()}. Throwing exception.');
    throw Exception('Swarm is closed');
  }
  _logger.warning('Swarm.newStream: Swarm is open for peer ${peerId.toString()}.');

  // Get or create a connection to the peer
  _logger.warning('Swarm.newStream: Calling dialPeer(context, ${peerId.toString()}).');
  final Conn conn; // Type is Conn, but runtime type should be SwarmConn
  try {
    conn = await dialPeer(context, peerId);
  } catch (e, st) {
    _logger.severe('Swarm.newStream: Error from dialPeer for ${peerId.toString()}: $e\n$st');
    rethrow;
  }
  _logger.warning('Swarm.newStream: Successfully dialed peer ${peerId.toString()}. Conn runtimeType: ${conn.runtimeType}, Conn ID: ${conn.id}, Conn local: ${conn.localPeer}, Conn remote: ${conn.remotePeer}');

  if (conn is! SwarmConn) {
      _logger.severe('Swarm.newStream: conn from dialPeer is NOT SwarmConn. Actual type: ${conn.runtimeType}. Peer: ${peerId.toString()}');
      throw StateError('Connection from dialPeer is not a SwarmConn. Type: ${conn.runtimeType}');
  }

  // Create a new stream - let the underlying connection manage stream IDs
  _logger.warning('Swarm.newStream: About to call (conn as SwarmConn).newStream() for peer ${peerId.toString()} on SwarmConn ${conn.id}.');

  final P2PStream stream;
  try {
    stream = await conn.newStream(context);
  } catch (e, st) {
    _logger.severe('Swarm.newStream: Error from (conn as SwarmConn).newStream() for peer ${peerId.toString()}: $e\n$st');
    rethrow;
  }

  _logger.warning('Swarm.newStream: Successfully called (conn as SwarmConn).newStream() for peer ${peerId.toString()}. Returned Stream ID: ${stream.id()}, Stream protocol: ${stream.protocol}');
  // Note: Protocol negotiation (multistreamMuxer.selectOneOf) happens in BasicHost.newStream *after* this Swarm.newStream returns.
  // So, a log for "Protocol negotiation complete" belongs in BasicHost.newStream.

  return stream;
}