selectProtoOrFail function

Future<void> selectProtoOrFail(
  1. ProtocolID proto,
  2. P2PStream stream
)

SelectProtoOrFail performs the initial multistream handshake to inform the muxer of the protocol that will be used to communicate on this stream. It returns an error if the muxer does not support the protocol.

Implementation

Future<void> selectProtoOrFail(ProtocolID proto, P2PStream<dynamic> stream) async {
  try {
    // Send the multistream protocol ID and the requested protocol
    await writeDelimited(stream, utf8.encode(protocolID));
    await writeDelimited(stream, utf8.encode(proto));

    // Read the multistream header response
    final headerResponse = await readNextToken(stream);
    if (headerResponse != protocolID) {
      throw FormatException('Received mismatch in protocol id');
    }

    // Read the protocol response
    final protoResponse = await readNextToken(stream);
    if (protoResponse == 'na') {
      throw ProtocolNotSupportedException([proto]);
    } else if (protoResponse != proto) {
      throw UnrecognizedResponseException(actual: protoResponse, expected: proto);
    }

    // Success - protocol selected
    return;
  } catch (e) {
    if (e is! ProtocolNotSupportedException &&
        e is! UnrecognizedResponseException &&
        e is! FormatException) {
      await stream.reset();
    }
    rethrow;
  }
}