NFC и API бесконтактного взаимодействия
Предложение подключения
Процесс предложения подключения состоит из двух частей: объявление о возможности принять подключение и прослушивание на предмет входящих подключений.
Предполагая, что доступен какой-либо способ взаимодействия, первый шаг заключается в конфигурировании PeerFinder с помощью displayName , которое будет видно другим устройствам, когда вы объявите о возможности подключения и установка параметров allowBluetooth, allowInfrastructure, и allowWiFiDirect желаемым образом для позволения обнаружения устройства с помощью дополнительных способов связи (infrastructure jnyjcbncz r TCP/IP). Если не устанавливать ни один из этих флагов, то соединение, всё равно, будет доступно посредством NFC-касания, которое активировано всегда.
Далее, нужно настроить обработчик для события PeerFinder.onconnectionrequested (http://msdn.microsoft.com/library/windows/apps/windows.networking.proximity.peerfinder.connectionrequested.aspx), за которым следует вызов статического метода PeerFinder.start (снова, ProxNS это переменная для пространства имен):
ProxNS.PeerFinder.onconnectionrequested = connectionRequestedEventHandler; ProxNS.PeerFinder.start();
Примечание. connectionrequested это событие, которое исходит из WinRT. Так как вы, возможно, будете прослушивать это событие лишь временно, не забудьте вызвать removeEventListener или присвоить null свойству события для предотвращения утечки памяти. Подробнее об этом – в Главе 3 курса "Введение в разработку приложений для Windows 8 с использованием HTML, CSS и JavaScript".
Событие connectionrequested вызывается, когда другое устройство принимает предложение соединения и вызывает ваше приложение по бесплатному каналу связи, в частности, через WiFi Direct или Bluetooth. Событие принимает объект ConnectionRequestedEventArgs ( http://msdn.microsoft.com/library/windows/apps/windows.networking.proximity.connectionrequestedeventargs.aspx), который содержит единственное свойство – peerInformation, экземпляр класса PeerInformation (http://msdn.microsoft.com/library/windows/apps/windows.networking.proximity.peerinformation.aspx). Это простой объект, он содержит лишь displayName, но этого достаточно чтобы установить соединение.
function connectionRequestedEventHandler(e) { requestingPeer = e.peerInformation; ProximityHelpers.displayStatus("Connection Requested from peer: " + requestingPeer.displayName); // Включает кнопку Accept (Принять) (и скрывает Send (отправить)и Message (Сообщение)) [некоторый код опущен] ProximityHelpers.id("peerFinder_AcceptRequest").style.display = "inline"; }
Соединение устанавливается путём передачи данного объекта PeerInformation в PeerFinder.connectAsync (http://msdn.microsoft.com/library/windows/apps/windows.networking.proximity.peerfinder.connectasync.aspx). Это вызовет показ запроса для получения согласия пользователя, и получив это согласие, обработчик завершения полкчит объект Windows.Networking.Sockets.StreamSocket, о котором мы уже говорили в Главе 3.
function peerFinder_AcceptRequest() { ProxNS.PeerFinder.connectAsync(requestingPeer).done(function (proximitySocket) { startSendReceive(proximitySocket); }); }
С этого момента вы можете отправлять любые данные, с использованием любого протокола, при условии, конечно, что приложение на другом конце сможет распознать то, что вы отправили. Это не проблема, когда на обеих концах соединения находится одно и то же приложение; разные приложения, конечно, нуждаются в использовании какого-то известного и одному и другому протокола. В примере "протокол" обмена предельно прост, но он отражает сущность всего этого процесса.
Если нужно прекратить объявление о доступности подключения, можно воспользоваться методом PeerFinder.stop. Для того, чтобы закрыть конкретное подключение, вызовите метод сокета close.
Установление соединения
С другой стороны бесконтактного взаимодействия, приложение может искать одноранговые приложения, которые предлагают подключение по WiFi Direct или Bluetooth. В примере о бесконтактном взаимодействии, кнопка Browse Peers (Найти доступные подключения) доступна, если доступен вид обнаружения browse. Нажатие на кнопку приводит к вызову следующей функции (js/PeerFinder.js), которая использует PeerFinder.findAllPeersAsync (http://msdn.microsoft.com/library/windows/apps/windows.networking.proximity.peerfinder.findallpeersasync.aspx) для заполнения списка возможных соединений, включая соединения от различных приложений:
function peerFinder_BrowsePeers() { // Очищение текущего списка опций [код опущен] ProxNS.PeerFinder.findAllPeersAsync().done(function (peerInfoCollection) { // Добавление найденного предложения о подключении в выпадающий список. for (i = 0; i<peerInfoCollection.size; i++) { var peerInformation = peerInfoCollection[i]; // Создание и добавление элемента опции с использованием peerInformation.displayName // к элементу управления peerFinder_FoundPeersList [код опущен] } }); }
Когда вы выбираете одно из предложений для подключения, пример берет его объект PeerInformation и вызывает PeerFinder.connectAsync как и ранее (при этом у пользователя запрашивается согласие):
function peerFinder_Connect() { var foundPeersList = ProximityHelpers.id("peerFinder_FoundPeersList"); var peerToConnect = discoveredPeers[foundPeersList.selectedIndex]; ProxNS.PeerFinder.connectAsync(peerToConnect).done( function (proximitySocket) { startSendReceive(proximitySocket); }); }
Снова, здесь вы получаете, в качестве результата StreamSocket , которым можно пользоваться так, как нужно. Для завершения соединения, вызовите метод сокета close.
Касание для соединения и касание для активации
Для того, чтобы обнаружить непосредственное сближение устройств с NFC-модулем (касание, поднесение) которое используется для соединения приложений, исполняющихся на двух устройствах, нужно прослушивать событие PeerFinder.ontriggeredConnectionStateChanged (http://msdn.microsoft.com/library/windows/apps/windows.networking.proximity.peerfinder.triggeredconnectionstatechanged.aspx) (событие WinRT, имя которого я написал, используя "верблюжий" стиль, чтобы его можно было нормально прочесть!). В ответ на это запускают PeerFinder:
ProxNS.PeerFinder.ontriggeredconnectionstatechanged = triggeredConnectionStateChangedEventHandler; ProxNS.PeerFinder.start();
Процесс соединения посредством касания проходит через последовательность изменения состояния (включая согласие пользователя), эти состояния описаны в перечислении TriggeredConnectState ( http://msdn.microsoft.com/library/windows/apps/windows.networking.proximity.triggeredconnectstate.aspx): listening, connecting, peerFound, completed, canceled, и failed. Каждое состояние включается в аргументы события, которые отправляются событию (TriggeredConnectionStateChangedEventArgs (http://msdn.microsoft.com/library/windows/apps/windows.networking.proximity.triggeredconnectionstatechangedeventargs.aspx)), и когда дело доходит до completed, свойство socket в аргументах события будет содержать StreamSocket для соединения:
function triggeredConnectionStateChangedEventHandler(e) { // [Другие случаи опущены] if (e.state === ProxNS.TriggeredConnectState.completed) { startSendReceive(e.socket); } }
Снова, с этого момента, возможна передача данных через сокет – NFC-касание – это лишь средство для установления соединения. И, снова, вызовите метод close сокета, когда завершите работу с ним.
Когда NFC-касание подразумевает связь экземпляров одного и того же приложения на разных устройствах, можно организовать и запуск приложения по касанию на одном из устройств. Таким образом, когда приложение исполняется на одном из устройств и запустило PeerFinder, Windows значет, что это за приложение и может произвести поиск его копии на другом устройстве. Если устройство найдено, система может его запустить (или активировать, если оно уже запущено). Обработчик активации приложения вызывается с видом активации launch, где eventArgs.detail.arguments будет содержать строку "Windows.Networking.Proximity.PeerFinder:StreamSocket" (смотрите js/default.js):
var tapLaunch = ((eventObject.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) pgpg (eventObject.detail.arguments === "Windows.Networking.Proximity.PeerFinder:StreamSocket")); if (tapLaunch) { url = scenarios[0].url; // Выполнение сценария 0, если запущено по касанию, для запуска PeerFinder. } return WinJS.Navigation.navigate(url, tapLaunch);
Код Сценария 1 учитывает это условие (параметр tapLaunch в WinJS.Navigation.Navigate установлен в true) и автоматически вызвает PeerFinder.start вместо того, чтобы ожидать нажатия на кнопку. При запуске, приложение так же регистрирует собственный обработчик triggeredConnectionStateChanged таким образом оно получит сокет, когда процесс соединения завершится.