Condividi tramite


Associazione di un set alla proprietà DeviceInformationPairing.Custom

Nota

Alcune informazioni sono relative a un prodotto non definitivo, che potrebbe subire modifiche sostanziali prima del rilascio sul mercato. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.

Usare le API Windows.Devices.Enumeration per associare i dispositivi come set.

Windows supporta l'associazione di una raccolta di dispositivi come set. La piattaforma supporta due tipi di set.

  • Set individuato automaticamente. Ciò si verifica quando un protocollo ,ad esempio Bluetooth LE, individua automaticamente altri endpoint che appartengono al set durante l'associazione di un endpoint primario. Ad esempio, mentre un utente sta parando l'auricolare destro su Bluetooth LE, lo stack di protocolli potrebbe individuare l'auricolare sinistro; in modo che entrambi possano essere associati insieme come un set.
  • Set esplicito. Questi sono utili quando un dispositivo viene individuato su più di un protocollo. Ad esempio, le stampanti IPP (Internet Printing Protocol) vengono in genere individuate su tre protocolli: IPP, WSD ed eSCL. Quando vengono individuati più endpoint per lo stesso dispositivo, possono essere associati in modo esplicito come set.

Esempio di codice per un set individuato automaticamente (stile Bluetooth)

Questo esempio di codice implementa l'associazione di set individuati automaticamente (in stile Bluetooth) usando un oggetto di associazione personalizzato. Come per un'implementazione tipica dell'associazione personalizzata, è necessario un gestore di associazione richiesto per gestire la cerimonia di associazione. In questo caso, l'esempio di codice implementa solo la cerimonia di associazione conferma . La parte nuova e interessante consiste nell'aggiungere un gestore di associazione-set-member-requested .

Il gestore set-member-consente alla piattaforma di tentare di associare il dispositivo passato come set. Senza tale gestore, lo stack di protocolli non tenterà di enumerare i membri di un set di associazione. Il protocollo Bluetooth individua i membri impostati come parte della finalizzazione dell'associazione, quindi il gestore set viene chiamato qualche ora dopo il suo gestore di cerimonia. In questo flusso, il gestore set in genere può aspettarsi di essere chiamato una volta dopo aver gestito la cerimonia con un elenco fisso di membri del set; il che significa che il protocollo individua tutti gli endpoint che può essere usato durante l'associazione e che non verrà più individuata in un secondo momento.

Questo esempio di codice associa in modo sincrono tutti i membri del set individuato con la stessa routine BtSetPairing usata per associare il dispositivo o l'endpoint primario. Anche l'associazione in parallelo è supportata e potrebbe essere più efficiente per lo scenario in uso. Ma per semplicità, questo non è illustrato nell'esempio di codice. Poiché si associano anche i membri set a un gestore set, possono potenzialmente produrre in modo ricorsivo più membri impostati da associare. In genere, tuttavia, il gestore set per i membri del set individuato visualizzerà probabilmente solo l'individuazione completata con il vettore membro impostato vuoto.

Nota

Questo esempio di codice è senza il contesto di uno scenario o di un'app più grande; ma un'app dovrebbe probabilmente tenere traccia dei dispositivi associati e dei risultati dell'associazione. Per consentire all'app di capire se l'intera operazione di associazione del set è riuscita o meno.

Nota

Queste API sono in genere asincrone. Le operazioni di associazione hanno thread di lavoro propri e i gestori vengono chiamati su thread diversi. Il codice non deve essere bloccato con la frequenza con cui viene eseguito questo esempio di codice.

Esempio di codice in C++/WinRT

void PairingTests::BtSetPairing(DeviceInformation device)
{
    DevicePairingKinds ceremonies = DevicePairingKinds::ConfirmOnly;
    auto customPairing = device.Pairing().Custom();
    event_revoker ceremonyEventToken = customPairing.PairingRequested(
        { this, &PairingTests::PairingRequestedHandler });
    event_revoker setEventToken = customPairing.PairingSetMembersRequested(
        { this, &PairingTests::PairingSetMembersRequestedHandler });

    DevicePairingResult result = customPairing.PairAsync(ceremonies).get();

    if (DevicePairingResultStatus::Paired == result.Status()) // Pairing worked.
    else // Handle pairing failure.
}

void PairingTests::PairingRequestedHandler(DeviceInformationCustomPairing const&,
    DevicePairingRequestedEventArgs const& args)
{
    switch (args.PairingKind())
    {
    case DevicePairingKinds::ConfirmOnly:
        args.Accept();
        break;
    default:
        // This code example doesn't implement other ceremonies.
        // The handler wouldn't be called for ceremonies that the app didn't register.
    }
}

void PairingTests::PairingSetMembersRequestedHandler(DeviceInformationCustomPairing
    const&, DevicePairingSetMembersRequestedEventArgs const& args)
{
    switch (args.Status())
    {
    case DevicePairingAddPairingSetMemberStatus::SetDiscoveryCompletedByProtocol:
        // This is the expected result if we started set pairing 
        // a Bluetooth device. Note: there still might be no set members.
        break;
    case DevicePairingAddPairingSetMemberStatus::SetDiscoveryPartiallyCompletedByProtocol:
        // The protocol enumerated some but not all set members.
        break;
    case DevicePairingAddPairingSetMemberStatus::SetDiscoveryNotAttemptedByProtocol:
        // Not expected for Bluetooth.
        // This constant implies that the protocol likely doesn't support set-pairing.
    default:
        // The other constants aren't expected in an auto-discovered Bluetooth set scenario.
        // Error handling can go here.
    }

    for (auto setMember : args.PairingSetMembers())
    {
        BtSetPairing(setMember);
    }
}

Esempio di codice per un set esplicito (tipo IPP)

Questo esempio di codice implementa l'associazione esplicita di set usando un oggetto di associazione personalizzato. Come per un'implementazione tipica dell'associazione personalizzata, è necessario un gestore di associazione richiesto per gestire la cerimonia di associazione. In questo caso, l'esempio di codice implementa solo la cerimonia di associazione conferma . Come per l'esempio di codice Bluetooth, la parte nuova e interessante consiste nell'aggiungere un gestore di associazione set-membro richiesto . Il gestore dei membri del set consente alla piattaforma di tentare di associare i dispositivi come set.

Rispetto allo scenario di associazione di set in stile Bluetooth, questo esempio di codice aggiunge in modo esplicito i dispositivi al set. Rispetto al Bluetooth, il gestore set implica qualcosa di leggermente diverso dai protocolli correlati all'associazione di stampanti IPP. Implica che i client gestiscono l'individuazione dei dispositivi sui vari protocolli e che lo stato PnP e le code di stampa create come risultato dell'associazione di tutti i membri del set devono essere sincronizzati.

Per mantenere semplice l'implementazione dell'esempio di codice, si presuppone che un vettore di endpoint membro impostati sia stato individuato in anticipo e passato come parametro insieme al dispositivo primario. Ad esempio, in uno scenario IPP tipico, gli endpoint vengono individuati in ordine arbitrario. Quindi il dispositivo primario potrebbe essere stato scoperto su WSD per esempio; e quindi il vettore conterrà dispositivi che rappresentano gli endpoint individuati tramite IPP e eSCL. Ma qualsiasi combinazione è possibile e valida. Aggiunge membri impostati all'oggetto di associazione personalizzato del dispositivo primario nel thread principale dell'app e quindi chiama PairAsync.

Nota

In pratica, è possibile aggiungere membri a un oggetto di associazione personalizzato in qualsiasi momento in qualsiasi thread. Le operazioni su un protocollo possono richiedere molto tempo o potrebbero anche essere bloccate fino al timeout, in modo che la sovrapposizione sia utile. Valutare la possibilità di sfruttare il parallelismo dell'API per aggiungere e associare dispositivi contemporaneamente. Questo è possibile anche mentre si enumerare i dispositivi in rete. I vantaggi dell'associazione come set si applicano in genere.

Con questa implementazione, il membro del set primario verrà associato simultaneamente ai membri del set. I membri del set vengono associati uno alla volta in modo sincrono nel gestore. Ma anche in questo caso, possono essere abbinati in parallelo per migliorare l'efficienza.

Gli oggetti nodo del dispositivo in PnP vengono spesso creati in seguito all'associazione. Nel caso di IPP, i nodi del dispositivo vengono sempre creati per ogni endpoint dopo l'associazione. Questa API di associazione di set sincronizza in modo implicito la creazione del nodo del dispositivo tra gli endpoint nel set. Nel flusso di questo esempio di codice, tutti i nodi del dispositivo verranno sincronizzati perché tutti i membri del set vengono aggiunti prima dell'avvio dell'associazione. Per altri dettagli su come questa API sincronizza i nodi del dispositivo in PnP, vedere la sezione Commenti generali in questo argomento.

Nota

Questo esempio di codice è senza il contesto di uno scenario o di un'app più grande; ma un'app dovrebbe probabilmente tenere traccia dei dispositivi associati e dei risultati dell'associazione. Per consentire all'app di capire se l'intera operazione di associazione del set è riuscita o meno.

Esempio di codice in C++/WinRT

void PairingTests::IppSetPairing(DeviceInformation device,
    std::vector<DeviceInformation> const& setMemberDevices)
{
    DevicePairingKinds ceremonies = DevicePairingKinds::ConfirmOnly;
    auto customPairing = device.Pairing().Custom();
    event_revoker ceremonyEventToken = customPairing.PairingRequested({ this,
                     &PairingTests::PairingRequestedHandler });
    event_revoker setEventToken = customPairing.PairingSetMembersRequested({ this,
                  &PairingTests::PairingSetMembersRequestedHandler });

    if (setMemberDevices)
    {
        for (auto setDevice : setMemberDevices)
        {
            customPairing.AddPairingSetMember(setDevice);
        }
    }

    DevicePairingResult result = customPairing.PairAsync(ceremonies).get();

    if (DevicePairingResultStatus::Paired == result.Status()) // Pairing worked.
    else // Handle pairing failure.
}

void PairingTests::PairingRequestedHandler(DeviceInformationCustomPairing const&,
    DevicePairingRequestedEventArgs const& args)
{
    switch (args.PairingKind())
    {
    case DevicePairingKinds::ConfirmOnly:
        args.Accept();
        break;
    }
}

void PairingTests::PairingSetMembersRequestedHandler(DeviceInformationCustomPairing const&,
    DevicePairingSetMembersRequestedEventArgs args)
{
    switch (args.Status())
    {
    case DevicePairingAddPairingSetMemberStatus::AddedToSet:
        // This is the expected result of adding a set member(s) to
        // a Bluetooth device. Note: there still might be no set members.
        break;
    case DevicePairingAddPairingSetMemberStatus::CouldNotBeAddedToSet:
        // Means we failed to add set member(s).
        break;
    case DevicePairingAddPairingSetMemberStatus::SetDiscoveryNotAttemptedByProtocol:
    default:
        // The other constants aren't expected in an auto-discovered Bluetooth set scenario.
        // Error handling can go here.
    }

    for (auto setMember : args.PairingSetMembers())
    {
        IppSetPairing(setMember, nullptr);
    }
}

Commento generale

Associazione di set individuata automaticamente (in stile Bluetooth)

Questa API è necessaria per eseguire l'associazione di set in stile Bluetooth in cui i membri impostati vengono individuati dal protocollo dopo l'associazione dell'endpoint primario. Un semplice esempio potrebbe essere un set di auricolari wireless. Quando l'abbinamento del primo auricolare viene finalizzato, il dispositivo informa il PC che c'è un secondo dispositivo da associare come parte del set. L'API di associazione personalizzata viene estesa per consentire alle app di gestire le operazioni di set tramite il nuovo gestore di stato del membro di aggiunta.

Associazione di set espliciti (in stile IPP)

Analogamente, è anche possibile usare questa API per associare qualsiasi gruppo di dispositivi dell'endpoint di associazione (AEP) come set. Con un oggetto di associazione personalizzato, l'app può aggiungere altri endpoint al set di associazione in qualsiasi momento in qualsiasi thread. Questo è per impostazione predefinita perché l'individuazione e l'associazione dei dispositivi in una rete possono richiedere molto tempo per ogni dispositivo, quindi non si vuole serializzare queste operazioni quando è possibile evitarlo.

È particolarmente utile associare i set quando si individuano dispositivi su molti protocolli in cui il protocollo e gli stack di dispositivi non sono facilmente coordinati. Ad esempio, una stampante di rete moderna verrà probabilmente individuata da Windows con tre protocolli di rete diversi, ognuno dei quali produce endpoint di associazione. In tal caso, l'associazione di tutti e tre gli endpoint come set è molto utile per un paio di motivi: evita la scoperta sprecato in rete e crea una singola coda di stampa semplificata.

Anche se una stampante di rete non è associata come set, lo spooler di stampa tenta comunque di creare una singola coda di stampa per utente indipendentemente dal fatto che possa essere abbinata a più protocolli. Se inizialmente una stampante viene abbinata su un protocollo, il sistema operativo tenterà di individuarlo sugli altri protocolli supportati e associarlo a tutti per evitare code di stampa duplicate. In genere, il sistema operativo può farlo rapidamente e correttamente e produrre una coda di stampa semplificata.

Tuttavia, se l'app ha già individuato tutti gli endpoint per la stampante, questo passaggio di nuova individuazione è sprecato. E peggio, può aggiungere lunghi ritardi prima che la stampante sia pronta per l'uso. Inoltre, se i protocolli sono troppo out-of-sync o ritardati, lo spooler potrebbe dover creare code di stampa aggiuntive per la stessa stampante, con confusione per gli utenti finali.

L'associazione di tutti gli endpoint contemporaneamente come set consente di evitare la scoperta potenzialmente lenta. Garantisce che lo stato PnP sia sincronizzato e produa code di stampa ottimizzate ottimali.

Sincronizzazione dei nodi del dispositivo

Quando i dispositivi vengono associati come set a questa API, lo stato del dispositivo PnP risultante viene facilmente sincronizzato. L'API non vincola quando un'app può aggiungere un membro impostato, ma esistono limiti quando la piattaforma può sincronizzare i nodi del dispositivo. La sincronizzazione dei nodi del dispositivo si blocca fino a quando non viene completata l'associazione di tutti gli endpoint nel set. Successivamente, tutti i nodi del dispositivo per tutti gli endpoint vengono creati contemporaneamente. È possibile aggiungere altri membri impostati al set dopo tale punto, ma non viene bloccata la creazione successiva del nodo del dispositivo, ma viene creata immediatamente.

  • La creazione del nodo del dispositivo viene sincronizzata quando:
    • I membri set vengono aggiunti prima dell'avvio dell'associazione.
    • I membri set vengono aggiunti mentre almeno uno dei membri del set non viene finalizzato.
  • La creazione del nodo del dispositivo non è sincronizzata:
    • Ogni volta che tutti i membri del set aggiunti sono stati finalizzati.

In pratica, l'API non consente a un'app di controllare quando viene completata la finalizzazione della cerimonia per influenzare questo comportamento sulla sincronizzazione dei nodi del dispositivo. L'approssimazione più vicina sarebbe quando l'app sceglie di completare la cerimonia. Un'associazione non può finalizzare finché il gestore della cerimonia dell'app non viene restituito; è quindi l'ultima possibilità dell'app di influenzare quando tutti i membri del set vengono finalizzati.