def _alpn_handler(self, alpn_protocol: str) -> None:
        """
        Callback which is invoked by the TLS engine at most once, when the
        ALPN negotiation completes.

        At this point, TLS extensions have been received so we can parse the
        transport parameters.
        """
        # Parse the remote transport parameters.
        for ext_type, ext_data in self.tls.received_extensions:
            if ext_type == tls.ExtensionType.QUIC_TRANSPORT_PARAMETERS:
                self._parse_transport_parameters(ext_data)
                break
        else:
            raise QuicConnectionError(
                error_code=QuicErrorCode.CRYPTO_ERROR
                + tls.AlertDescription.missing_extension,
                frame_type=self._crypto_frame_type,
                reason_phrase="No QUIC transport parameters received",
            )

        # For servers, determine the Negotiated Version.
        if not self._is_client and not self._version_negotiated_compatible:
            if self._remote_version_information is not None:
                # Pick the first version we support in the client's available versions,
                # which is compatible with the current version.
                for version in self._remote_version_information.available_versions:
                    if version == self._version:
                        # Stay with the current version.
                        break
                    elif (
                        version in self._configuration.supported_versions
                        and is_version_compatible(self._version, version)
                    ):
                        # Change version.
                        self._version = version
                        self._cryptos[tls.Epoch.INITIAL] = self._cryptos_initial[
                            version
                        ]

                        # Update our transport parameters to reflect the chosen version.
                        self.tls.handshake_extensions = [
                            (
                                tls.ExtensionType.QUIC_TRANSPORT_PARAMETERS,
                                self._serialize_transport_parameters(),
                            )
                        ]
                        break
            self._version_negotiated_compatible = True
            self._logger.info(
                "Negotiated protocol version %s", pretty_protocol_version(self._version)
            )

        # Notify the application.
        self._events.append(events.ProtocolNegotiated(alpn_protocol=alpn_protocol))

        Callback which is invoked by the TLS engine at most once, when the
        ALPN negotiation completes.

        At this point, TLS extensions have been received so we can parse the
        transport parameters.
        
src/aioquic/quic/connection.py