Краткое руководство: подключение приложений с помощью касания или обзора (HTML)

[ Эта статья адресована разработчикам приложений среды выполнения Windows для Windows 8.x и Windows Phone 8.x. При разработке приложений для Windows 10 см. раздел последняя документация]

Используя близкое взаимодействие, вы можете создать соединение между двумя устройствами с помощью простого жеста касания или выполнив обзор устройств в диапазоне беспроводной сети. Вам не нужно подключаться к сети. Можно соприкоснуться двумя устройствами или использовать для подключения Wi-Fi Direct.

Чтобы инициировать подключение между двумя экземплярами приложения с помощью жеста касания, большинству устройств требуется технология NFC. На компьютере этот канал связи можно создать посредством Bluetooth, Wi-Fi Direct или сети с инфраструктурой. На устройстве под управлением Windows Phone можно установить подключение по Bluetooth или по сети с инфраструктурой. Wi-Fi Direct не поддерживается в Windows Phone. Это означает, что подключение путем соприкосновения между устройством Windows Phone и компьютером возможно, но такое подключение должно использовать либо Bluetooth, либо сеть с инфраструктурой.

При жесте касания, если два устройства находятся на расстоянии 3–4 сантиметров друг от друга, модуль близкого взаимодействия уведомляет обе системы. Касание позволит вам настроить канал длительной связи с помощью сети с инфраструктурой, Wi-Fi Direct или Bluetooth. Жесты касания доступны только в случае, если на устройстве установлено оборудование бесконтактной связи ближнего действия (NFC). Обзор по Wi-Fi Direct доступен только в случае, если адаптер беспроводных сетей поддерживает Wi-Fi Direct.

Вы также можете использовать близкое взаимодействие, чтобы настроить канал длительной связи с одноранговым приложением в диапазоне беспроводной сети.

В этом разделе показано, как использовать близкое взаимодействие, чтобы создать соединение между одноранговыми приложениями (например, играми), между приложениями, которые совместно используют содержимое и т. п.

Пример в этом разделе демонстрирует, как использовать близкое взаимодействие и класс PeerFinder, чтобы создать длительное соединение через сокеты с одноранговым приложением на другом устройстве.

Если одноранговое приложение не выполняется на переднем плане на целевом устройстве, то для соединений, запускаемых касанием, модуль близкого взаимодействия предлагает пользователю активировать приложение на целевом устройстве. Если одноранговое приложение не установлено на целевом устройстве, модуль близкого взаимодействия предлагает пользователю целевого устройства установить приложение из Магазина Windows. Подробнее об активации приложений жестом касания см. в разделе "Активация приложений с помощью близкого взаимодействия" в статье Поддержка близкого взаимодействия и касания.

Цель: Создайте соединение между двумя устройствами путем их соприкосновения или обзора по беспроводной сети.

Необходимые условия

Microsoft Visual Studio Express 2012 для Windows 8

Инструкции

1. Создание нового проекта и включение возможности близкого взаимодействия

  1. Откройте приложение Visual Studio Express 2012 для Windows 8 и выберите New Project (Создать проект) в меню File (Файл). В разделе JavaScript выберите Blank Application (Пустое приложение). Назовите приложение ProximityConnect и нажмите кнопку OK.
  2. Откройте файл Package.appxmanifest и перейдите на вкладку Capabilities (Возможности). Включите возможность Близкое взаимодействие. Сохраните и закройте файл манифеста.

2. Добавление пользовательского интерфейса на языке HTML

Откройте файл Default.html и добавьте следующий HTML-код в раздел <body>.

<div style="position:absolute;margin:0">
    Display Name: <input type="text" id="displayNameTextBox" style="width:300px" />
    <button id="advertiseForPeersButton">Advertise for a Connection</button>
    <button id="acceptButton">Accept Connection</button>
    <button id="findPeersButton">Browse for Peers</button>
    <button id="stopFindingPeersButton">Stop Browsing for Peers</button><br />
    <input id="sendMessageText" type="text" style="width:200px" />
    <button id="sendMessageButton">Send Message</button><br />
    <div id="messageDiv" style="position:relative;width:600px"></div>
   </div>

3. Добавление кода инициализации

Код, добавляемый на этом этапе, связывает функции с событиями нажатия кнопок HTML. Эти функции будут добавлены на следующих этапах как обработчики событий. Функция ярлыка, id, включена для удобства доступа к функции getElementById.

Откройте папку js. Откройте файл Default.js и замените функцию по умолчанию activated следующим кодом.

app.onactivated = function (args) {
    if (args.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) {

        id("advertiseForPeersButton").addEventListener("click", advertiseForPeers);
        id("acceptButton").addEventListener("click", acceptConnection);
        id("findPeersButton").addEventListener("click", findPeers);
        id("stopFindingPeersButton").addEventListener("click", stopFindingPeers);
        displayNameTextBox.value = Windows.Networking.Proximity.PeerFinder.displayName;
        Windows.Networking.Proximity.PeerFinder.addEventListener("connectionrequested", connectionRequested);

        // Detect if app launched from a tap.
        if ((args.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) &&
            (args.detail.arguments === "Windows.Networking.Proximity.PeerFinder:StreamSocket")) {

            advertiseForPeers(true);
        }

        args.setPromise(WinJS.UI.processAll());
    }
};

function id(elementId) {
    return document.getElementById(elementId);
}

4. Добавление кода для связи с одноранговым приложением

На этом этапе вы добавите код для событий нажатия кнопок. Также вы добавите метод для записи в поток пользовательского интерфейса. Код в обработчике событий кнопки advertiseForPeersButton задает имя однорангового узла для локального устройства и запускает PeerFinder. Если инициированные (касанием) подключения поддерживаются, код идентифицирует обработчик события triggeredConnectionStateChanged. В обработчике события triggeredConnectionStateChanged код открывает сокет потока для передачи текстовых сообщений между одноранговыми приложениями.

Код в обработчике события кнопки findPeersButton вызывает метод findAllPeersAsync для обзора устройств в диапазоне беспроводной сети. Если обнаружен один или несколько одноранговых компьютеров, в примере вызывается метод connectAsync для соединения с первым обнаруженным компьютером. Этот пример предназначен только для демонстрации. Вам нужно дать пользователю возможность выбрать компьютер из списка одноранговых компьютеров, а затем соединиться с выбранным компьютером.

Код включает в себя обработчик события connectionRequested, которое возникает, когда одноранговый компьютер соединяется с вашим, вызывая метод connectAsync. Вы можете нажать кнопку Принять соединение, чтобы согласиться на соединение.

Код в обработчике события кнопки stopFindingPeersButton вызывает метод stop. Этот метод останавливает объявления и поиск одноранговых компьютеров обработчиком событий при беспроводном подключении и при касаниях.

В файле Default.js добавьте следующий код после функции id.

var started = false;

// Click event for "Advertise" button.
function advertiseForPeers(launchedFromTap) {
    Windows.Networking.Proximity.PeerFinder.displayName = displayNameTextBox.Text;

    if (Windows.Networking.Proximity.PeerFinder.supportedDiscoveryTypes &
        Windows.Networking.Proximity.PeerDiscoveryTypes.triggered) {

        Windows.Networking.Proximity.PeerFinder.addEventListener(
            "triggeredconnectionstatechanged", triggeredConnectionStateChanged);

        id("messageDiv").innerHTML +=
            "You can tap to connect a peer device that is " +
            "also advertising for a connection.<br />";
    } else {
        id("messageDiv").innerHTML +=
            "Tap to connect is not supported.<br />";
    }

    if (!launchedFromTap) {
        if (!(Windows.Networking.Proximity.PeerFinder.SupportedDiscoveryTypes &
              Windows.Networking.Proximity.PeerDiscoveryTypes.Browse)) {
            id("messageDiv").innerHTML +=
                "Peer discovery using Wi-Fi Direct is not supported.<br />";
        }
    }

    if (!started) {
        Windows.Networking.Proximity.PeerFinder.start();
        started = true;
    }
}

function triggeredConnectionStateChanged(e) {
    if (e.state === Windows.Networking.Proximity.TriggeredConnectState.peerFound) {
        id("messageDiv").innerHTML +=
            "Peer found. You may now pull your devices out of proximity.<br />";
    }
    if (e.state === Windows.Networking.Proximity.TriggeredConnectState.completed) {
        id("messageDiv").innerHTML += "Connected. You may now send a message.<br />";
        sendMessage(e.socket);
    }
}


// Click event for "Browse" button.
function findPeers() {
    if (Windows.Networking.Proximity.PeerFinder.supportedDiscoveryTypes &
        Windows.Networking.Proximity.PeerDiscoveryTypes.browse) {

        Windows.Networking.Proximity.PeerFinder.findAllPeersAsync().done(
    function (peerInfoCollection) {
        if (peerInfoCollection.length > 0) {
            // Connect to first peer found - example only.
            // In your app, provide the user with a list of available peers.
            connectToPeer(peerInfoCollection[0]);
        }
    },
    function (err) {
        id("messageDiv").innerHTML += "Error finding peers: " + err + "<br />";
    });
    } else {
        id("messageDiv").innerHTML +=
        "Peer discovery using Wi-Fi Direct is not supported.<br />";
    }
}

function connectToPeer(peerInfo) {
    id("messageDiv").innerHTML += ("Peer found. Connecting to " + peerInfo.displayName + "<br />");
    Windows.Networking.Proximity.PeerFinder.connectAsync(peerInfo).done(
        function (socket) {
            id("messageDiv").innerHTML += "Connection successful. You may now send messages.<br />";
            sendMessage(socket);
        },
        function (err) {
            id("messageDiv").innerHTML += "Connection failed: " + err + "<br />";
        });

    requestingPeer = null;
}

function stopFindingPeers() {
    Windows.Networking.Proximity.PeerFinder.stop();
    started = false;
    if (proximitySocket != null) { closeSocket(); }
}

// Handle external connection requests.
var requestingPeer;

function connectionRequested(e) {
    id("messageDiv").innerHTML +=
        "Connection requested by " + e.peerInformation.DisplayName + ". " +
        "Click 'Accept Connection' to connect.";
    requestingPeer = e.PeerInformation;
}

function acceptConnection() {
    if (requestingPeer == null) {
        id("messageDiv").innerHTML += "No peer connection has been requested.";
        return;
    }

    connectToPeer(requestingPeer);
}

5. Добавление кода для отправки и получения сообщений с помощью ProximityStreamSocket

Когда соединение успешно установлено, код передает объект ProximityStreamSocket, созданный в результате соединения, функции sendMessage. Функция sendMessage устанавливает сетевое подключение к расположенному поблизости устройству. Это позволяет обмениваться сообщениями. Не забывайте всегда вызывать метод close объекта ProximityStreamSocket после завершения этих операций.

В файле Default.js добавьте следующий код после функции connectToPeer.

var proximitySocket;
var dataWriter;

// Reference socket streams for writing and reading messages.
function sendMessage(socket) {
    id("sendMessageButton").addEventListener("click", sendMessageText);

    // Get the network socket from the proximity connection.
    proximitySocket = socket;

    // Create DataWriter for writing messages to peers.
    dataWriter = new Windows.Storage.Streams.DataWriter(proximitySocket.outputStream);

    // Listen for messages from peers.
    var dataReader = new Windows.Storage.Streams.DataReader(proximitySocket.inputStream);
    startReader(proximitySocket, dataReader);
}

// Send a message to the socket.
function sendMessageText() {
    var msg = id("sendMessageText").value;

    if (msg.length > 0) {
        var msgLength = dataWriter.measureString(msg);
        dataWriter.writeInt32(msgLength);
        dataWriter.writeString(msg);
        dataWriter.storeAsync().done(
            function (byteCount) {
                if (byteCount > 0) {
                    id("messageDiv").innerHTML += "Message sent: " + msg + "<br />";
                } else {
                    id("messageDiv").innerHTML += "The remote peer closed the socket.";
                    closeSocket();
                }
            },
            function (err) {
                id("messageDiv").innerHTML += "Send error: " + err.message + "<br />";
                closeSocket();
            });
    }
}

// Read out and print the message received from the socket.
function startReader(socket, reader) {
    var initialLength = 4;
    reader.loadAsync(initialLength).done(
    function (byteCount) {
        if (byteCount > 0) {
            var msgLength = reader.readInt32();
            reader.loadAsync(msgLength).done(
                function (byteCount) {
                    if (byteCount > 0) {
                        var message = reader.readString(msgLength);
                        id("messageDiv").innerHTML += "Received message: " + message + "<br />";

                        // After receiving a message, listen for the next message.
                        startReader(socket, reader);
                    }
                    else {
                        id("messageDiv").innerHTML += "The remote peer closed the socket.";
                        closeSocket();
                    }
                },
                function (err) {
                    id("messageDiv").innerHTML += "Receive error: " + err.message + "<br />";
                    reader.close();
                });
        }
        else {
            id("messageDiv").innerHTML += "The remote peer closed the socket.";
            reader.close();
        }
    },
    function (err) {
        id("messageDiv").innerHTML += "Receive error: " + err.message + "<br />";
        reader.close();
    });
}

function closeSocket() {
    if (proximitySocket) {
        proximitySocket.close();
        proximitySocket = null;
    }

    if (dataWriter) {
        dataWriter.close();
        dataWriter = null;
    }
}

6. Запуск приложения

Чтобы проверить приложение в действии, запустите его на двух устройствах с включенной функцией близкого взаимодействия. Затем нажмите кнопку Advertise for a Connection (Объявление соединения) в обоих приложениях и соприкоснитесь устройствами. Если на обоих устройствах вместо касания используется Wi-Fi Direct, вы можете нажать кнопку rowse for Peers (Обзор одноранговых приложений) на одном из устройств, чтобы установить соединение.

Важно  

Действия, описанные в этом кратком руководстве, необходимо выполнять на двух устройствах. В случаях, когда используется жест касания, для каждого устройства должно быть установлено оборудование близкого взаимодействия, такое как приемник связи ближнего действия (NFC). В случаях, когда используется обзор по беспроводной сети, необходимы два компьютера с включенным Wi-Fi Direct или два устройства под управлением Windows Phone с включенным Bluetooth. Если у вас нет оборудования, которое поддерживает близкое взаимодействие, например приемника связи ближнего действия (NFC), можно использовать пример драйвера близкого взаимодействия, который входит в число примеров в комплекте разработки драйверов для Windows (WDK). Вы можете использовать пример драйвера, чтобы имитировать жест касания для сетевого подключения двух устройств. Информацию о скачивании WDK см. в разделе Комплект разработки драйверов для Windows (WDK). После установки WDK и примеров вы сможете найти пример драйвера близкого взаимодействия в каталоге src\nfp в расположении, в которое были установлены примеры WDK. Инструкции по сборке и выполнению симулятора см. в файле NetNfpProvider.html в каталоге src\nfp\net. После запуска симулятор выполняется в фоновом режиме, тогда как ваше приложение близкого взаимодействия выполняется на переднем плане. Для имитации касания ваше приложение должно находиться на переднем плане.

 

Краткая сводка и дальнейшие действия

В этом учебнике мы создали программу, которая использует жест касания или обзор беспроводной сети для соединения устройств.

Вы можете также использовать жесты касания, чтобы публиковать сообщения и подписываться на них. Пример см. в статье Публикация сообщений и подписка на них с помощью касания.

Связанные разделы

Рекомендации по разработке с использованием близкого взаимодействия

Поддержка близкого взаимодействия и касания

Тестирование и диагностика близкого взаимодействия в приложениях

Windows.Networking.Proximity namespace

Примеры

Пример близкого взаимодействия