Связывание набора с свойством DeviceInformationPairing.Custom
Примечание.
Некоторые сведения относятся к предварительной версии продукта, в которую перед коммерческим выпуском могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Используйте API Windows.Devices.Enumeration для связывания устройств в качестве набора.
Windows поддерживает связывание коллекции устройств в качестве набора. Платформа поддерживает два типа набора.
- Автоматически обнаруженный набор. Это происходит, когда протокол (например, Bluetooth LE) автоматически обнаруживает другие конечные точки, принадлежащие набору при связывании основной конечной точки. Например, в то время как пользователь анализирует правый ушиб через Bluetooth LE, стек протоколов может обнаружить левый ушиб; поэтому оба могут быть связаны в виде набора.
- Явный набор. Это полезно, если устройство обнаруживается по нескольким протоколам. Например, принтеры протокола IPP обычно обнаруживаются по трем протоколам: IPP, WSD и eSCL. При обнаружении нескольких конечных точек для одного устройства они могут быть явно связаны как набор.
Пример кода для автоматически обнаруженного набора (стиль Bluetooth)
В этом примере кода реализуется автоматическое обнаружение пар (Bluetooth-style) с помощью настраиваемого объекта связывания. Как и при типичной реализации настраиваемого связывания, для обработки церемонии связывания требуется запрашиваемый обработчик связывания. В этом случае пример кода реализует только церемонию подтверждения связывания. Новая и интересная часть — добавление обработчика, запрашиваемого с помощью парного набора-члена.
Обработчик set-member позволяет платформе пытаться связать переданное устройство в качестве набора. Без этого обработчика стек протоколов не попытается перечислить элементы парного набора. Протокол Bluetooth обнаруживает элементы набора как часть завершения связывания, поэтому обработчик набора вызывается через некоторое время после возврата обработчика церемонии. В этом потоке обработчик набора обычно может вызываться один раз после обработки церемонии с фиксированным списком элементов набора; это означает, что протокол обнаруживает все конечные точки, которые он может во время связывания, и он не будет обнаруживать больше позже.
Этот пример кода синхронно связывает все обнаруженные элементы набора с одной подпрограммой BtSetPairing , используемой для связывания основного устройства или конечной точки. Связывание их параллельно также поддерживается и может оказаться более эффективным для вашего сценария. Но для простоты это не показано в примере кода. Так как мы также связываем элементы набора с обработчиком набора, они могут рекурсивно создавать больше элементов набора для пары. Но обычно обработчик набора для обнаруженных элементов набора, вероятно, увидит только обнаружение, завершенное с пустым вектором элемента набора.
Примечание.
Этот пример кода отсутствует в контексте более крупного сценария или приложения; но приложению, вероятно, потребуется отслеживать, какие устройства она сопряжена, и результаты связывания. Это позволяет приложению получить представление о том, успешно ли выполнена операция связывания с набором.
Примечание.
Эти API обычно асинхронны. Операции связывания имеют собственные рабочие потоки, а обработчики вызываются в разных потоках. Код не должен блокироваться так часто, как это делает этот пример кода.
Пример кода в 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);
}
}
Пример кода для явного набора (стиль IPP)
В этом примере кода реализуется явное связывание наборов с помощью пользовательского объекта связывания. Как и при типичной реализации настраиваемого связывания, для обработки церемонии связывания требуется запрашиваемый обработчик связывания. В этом случае пример кода реализует только церемонию подтверждения связывания. Как и в примере кода Bluetooth, новая и интересная часть добавляет обработчик с парным набором-участником. Обработчик элементов набора позволяет платформе пытаться связать устройства в качестве набора.
По сравнению с сценарием связывания наборов в стиле Bluetooth этот пример кода явно добавляет устройства в набор. По сравнению с Bluetooth обработчик набора подразумевает что-то другое от протоколов, связанных с связыванием принтеров IPP. Это означает, что клиенты обрабатывают обнаружение устройств по различным протоколам, а состояние PnP и очереди печати, созданные в результате связывания всех элементов набора, должны быть синхронизированы.
Чтобы обеспечить простую реализацию примера кода, предполагается, что заранее обнаружен вектор конечных точек элементов набора и передан в качестве параметра вместе с основным устройством. Например, в типичном сценарии IPP конечные точки обнаруживаются в произвольном порядке. Таким образом, основное устройство может быть обнаружено через WSD для экземпляра; а затем вектор будет содержать устройства, представляющие конечные точки, обнаруженные по протоколу IPP и eSCL. Но любое сочетание возможно и допустимо. Он добавляет элементы в пользовательский объект связывания основного устройства в основном потоке приложения, а затем вызывает PairAsync.
Примечание.
На практике набор элементов может быть добавлен в пользовательский объект связывания в любое время в любом потоке. Операции с протоколом могут занять много времени или даже блокироваться до истечения времени ожидания, поэтому перекрывание их полезно. Рассмотрите возможность использования параллелизма API для одновременного добавления и связывания устройств. Это возможно даже во время перечисления устройств по проводу. Преимущества связывания их как набора по-прежнему применяются.
С этой реализацией основной элемент набора будет сопряжен одновременно с элементами набора. Элементы набора синхронно объединяются в обработчик. Но опять же, они могут быть связаны параллельно для повышения эффективности.
Объекты узла устройства в PnP часто создаются в результате связывания. В случае IPP узлы устройств всегда создаются для каждой конечной точки после связывания. Этот API связывания наборов неявно синхронизирует создание узла устройства между конечными точками в наборе. В этом примере кода все узлы устройства будут синхронизированы, так как все элементы набора добавляются перед началом связывания. Дополнительные сведения о том, как этот API синхронизирует узлы устройств в PnP, см. в разделе " Общие комментарии " в этом разделе.
Примечание.
Этот пример кода отсутствует в контексте более крупного сценария или приложения; но приложению, вероятно, потребуется отслеживать, какие устройства она сопряжена, и результаты связывания. Это позволяет приложению получить представление о том, успешно ли выполнена операция связывания с набором.
Пример кода в 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);
}
}
Общие комментарии
Автоматическое обнаружение (стиль Bluetooth) при связывании
Этот API необходим, чтобы выполнить связывание с набором стилей Bluetooth, где элементы набора обнаруживаются протоколом после связывания основной конечной точки. Простой пример может быть набор беспроводных ушибов. По мере завершения связывания первого уха устройство сообщает компьютеру о том, что есть второе устройство для связывания в составе набора. API пользовательского связывания расширен, чтобы приложения могли обрабатывать операции набора с помощью нового обработчика состояния элемента набора.
Явное связывание (стиль IPP)
Аналогичным образом этот API также можно использовать для связывания любой группы устройств конечной точки ассоциации (AEP) в качестве набора. С помощью пользовательского объекта связывания приложение может добавлять другие конечные точки в набор пар в любое время в любом потоке. Это связано с тем, что обнаружение устройств и связывание по сети может занять много времени для каждого устройства, поэтому мы не хотим сериализовать эти операции, когда мы можем избежать этого.
Особенно полезно связать наборы при обнаружении устройств по множеству протоколов, где стеки протоколов и устройств не легко согласованы. Например, современный сетевой принтер, скорее всего, будет обнаружен Windows с тремя разными сетевыми протоколами, каждый из которых создает конечные точки связи. В этом случае связывание всех трех конечных точек в качестве набора очень полезно по нескольким причинам: это позволяет избежать расточительного обнаружения по проводу, и он создает единую упрощенную очередь печати.
Даже если сетевой принтер не связан как набор, средство spooler печати по-прежнему пытается создать одну очередь печати на пользователя независимо от того, может ли она быть связана с несколькими протоколами. Если принтер изначально связан с одним протоколом, операционная система (ОС) попытается повторно обнаружить его по другим поддерживаемым протоколам и связать все эти протоколы, чтобы избежать повторяющихся очередей печати. Как правило, ОС может сделать это быстро и успешно и создать одну упрощенную очередь печати.
Однако если приложение уже обнаружило все конечные точки принтера, этот шаг повторного обнаружения является расточительным. И хуже, он может добавить длительные задержки, прежде чем принтер готов к использованию. Кроме того, если протоколы слишком не синхронизированы или отложены, может потребоваться создать дополнительные очереди печати для того же принтера, что запутано для конечных пользователей.
Связывание всех конечных точек одновременно в качестве набора позволяет избежать потенциально медленного повторного обнаружения. Это гарантирует синхронизацию состояния PnP и создает оптимальные оптимизированные очереди печати.
Синхронизация узлов устройства
Когда устройства объединяются как набор с этим API, то результирующее состояние устройства PnP удобно синхронизируется. API не ограничивает , когда приложение может добавить члена набора, но есть ограничения, когда платформа может синхронизировать узлы устройств. Синхронизация узлов устройств блокируется до тех пор, пока все конечные точки в наборе не будут завершены. После этого все узлы устройств для всех конечных точек создаются одновременно. Вы можете добавить больше элементов в набор после этого момента, но последующее создание узла устройства не блокируется, но создается сразу же.
- При создании узла устройства выполняется синхронизация:
- Перед началом связывания добавляются элементы.
- Установка элементов добавляется, хотя хотя бы один из элементов набора не завершен.
- Создание узла устройства не синхронизировано:
- Каждый раз после завершения всех добавленных элементов набора.
В практическом вопросе API не позволяет приложению контролировать, когда завершение церемонии завершается, чтобы повлиять на это поведение на синхронизации узлов устройств. Ближайшее приближение будет происходить, когда приложение решит завершить церемонию. Связывание не может завершиться до тех пор, пока обработчик церемонии приложения не возвращается; Таким образом, последний шанс приложения повлиять на завершение всех элементов набора.