クイック スタート: タップまたは参照によるアプリの接続 (HTML)

[この記事は、Windows ランタイム アプリを作成する Windows 8.x および Windows Phone 8.x 開発者を対象としています。Windows 10 向けの開発を行っている場合は、 「最新のドキュメント」をご覧ください]

近接通信を使うと、ユーザーは、単純なタップ ジェスチャのみで、またはワイヤレス範囲内にあるデバイスを参照して、2 つのデバイス間に接続を作成できます。ネットワークに接続している必要はありません。2 つのデバイスを同時にタップするか、Wi-Fi Direct を使って接続するだけです。

タップ ジェスチャを使ってアプリの 2 つのインスタンス間で接続を開始するには、ほとんどのデバイスに NFC が必要です。PC では、この接続チャネルは Bluetooth、Wi-Fi Direct、またはインフラストラクチャ ネットワークで設定できます。Windows Phone では、接続は Bluetooth またはインフラストラクチャ ネットワークで確立できます。Wi-Fi Direct は Windows Phone ではサポートされていません。 これは、Windows Phone と PC との間でタップによる接続は可能であるが、通信は Bluetooth またはインフラストラクチャ ネットワークを使った通信に制限されることを意味します。

タップ ジェスチャの場合、近接通信が有効な 2 つのデバイスを互いから 3 ~ 4 センチの間隔に近づけると、近接通信によって両方のシステムに通知されます。タップを使って、インフラストラクチャ ネットワーク、Wi-Fi Direct、または Bluetooth による長時間の接続チャネルを設定できます。タップ ジェスチャは、デバイスに近距離通信 (NFC) ハードウェアがインストールされている場合にのみ利用できます。Wi-Fi Direct 参照は、ワイヤレス アダプターが Wi-Fi Direct をサポートしている場合にのみ利用できます。

さらに、近接通信を使って、ワイヤレス範囲内にあるピア アプリへの長時間の接続チャネルを設定することもできます。

このトピックでは、近接通信を使って、ゲームなどのピア アプリ間やコンテンツを共有するアプリ間に接続を作る方法について説明します。

このトピックのサンプルでは、近接通信と PeerFinder クラスを使って、別のデバイス上のピア アプリに対する長時間のソケット接続を作る方法を示します。

タップによってトリガーされる接続では、ターゲット デバイス上のフォアグラウンドでピア アプリが実行されていない場合、近接通信により、ターゲット デバイス上のアプリをアクティブ化するようにユーザーに通知されます。ピア アプリがターゲット デバイスにインストールされていない場合、近接通信により、Windows ストアからアプリをインストールするようにターゲット デバイス上のユーザーに通知されます。タップ ジェスチャでアプリをアクティブ化する方法について詳しくは、「近接通信とタップのサポート」の「近接通信を使ったアプリのアクティブ化」をご覧ください。

目標: 近接通信タップまたはワイヤレス参照を使って 2 つのデバイス間に接続を作る。

必要条件

Microsoft Visual Studio Express 2012 for Windows 8

手順

1. 新しいプロジェクトを作り、近接通信を有効にする

  1. Visual Studio Express 2012 for Windows 8 を開き、[ファイル] メニューの [新しいプロジェクト] をクリックします。[Javascript] セクションで、[新しいアプリケーション] をクリックします。アプリケーションに ProximityConnect という名前を付け、[OK] をクリックします。
  2. Package.appxmanifest ファイルを開き、[機能] タブをクリックします。[近接通信] を選び、近接通信を有効にします。マニフェスト ファイルを保存して閉じます。

2. HTML UI を追加する

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. ピア アプリに接続するためのコードを追加する

この手順では、ボタンのクリック イベントのコードを追加します。さらに、UI スレッドへの書き込みを行うためのメソッドも追加します。advertiseForPeersButton ボタンのイベント ハンドラーのコードは、ローカル デバイスのピア名を設定し、PeerFinder を起動します。トリガーされる接続がサポートされている場合 (タップ)、コードは triggeredConnectionStateChanged イベントのイベント ハンドラーを識別します。triggeredConnectionStateChanged イベント ハンドラーで、ピア アプリ間でテキスト メッセージを送信するためのストリーム ソケットを開きます。

findPeersButton ボタンのイベント ハンドラーでは、findAllPeersAsync メソッドを呼び出して、ワイヤレス範囲内にあるデバイスを参照します。1 つまたは複数のピアが見つかった場合は、connectAsync メソッドを呼び出して、見つかった最初のピアに接続します。これは、サンプル用の動作にすぎません。実際には、ユーザーが選べるように接続可能なピアの一覧を表示し、ユーザーが選んだピアに接続する必要があります。

このコードには、ピアが connectAsync メソッドを呼び出して接続を開いたときに発生する connectionRequested イベントのイベント ハンドラーが含まれています。接続を受け入れるには、[Accept Connection] ボタンをクリックします。

stopFindingPeersButton ボタンのイベント ハンドラーのコードは、停止メソッドを呼び出します。このメソッドは、ワイヤレス接続かタップ ジェスチャかに関係なく、イベント ハンドラーによるアドバタイズとピアの参照を停止します。

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 関数は、近接デバイスとのネットワーク接続を開きます。これにより、メッセージをやり取りできるようになります。ProximityStreamSocket オブジェクトの処理の完了時は必ず close メソッドを呼び出してください。

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. アプリを実行する

アプリの動作を調べるために、近接通信が有効な 2 台のデバイス上でアプリを実行します。次に、両方のアプリで [Advertise for a Connection] ボタンをクリックした後、同時にデバイスをタップします。両方のデバイスで Wi-Fi Direct を使うことができる場合は、タップの代わりに一方のデバイス上で [Browse for Peers] ボタンをクリックして接続を作ります。

重要  

このクイック スタートは、2 台のデバイスで実行する必要があります。タップ ジェスチャを使うシナリオでは、各デバイスに近距離通信 (NFC) 無線などの近接通信機能がインストールされている必要があります。ワイヤレス参照を使うシナリオでは、Wi-Fi Direct が有効になっている 2 台の PC、または Bluetooth が有効になっている 2 台の Windows Phone が必要です。NFC 無線などの近接通信タップをサポートするハードウェアがない場合、Windows Driver Kit (WDK) サンプルに含まれる近接通信ドライバー サンプルを使うことができます。サンプル ドライバーを使って、2 つのデバイス間のネットワーク接続でタップ ジェスチャをシミュレートすることができます。WDK のダウンロード方法について詳しくは、Windows Driver Kit (WDK) に関するページをご覧ください。WDK とサンプルをインストールすると、近接通信のドライバー サンプルは、WDK サンプルをインストールした場所の src\nfp ディレクトリに配置されます。シミュレーターを構築し、実行する手順については、src\nfp\net ディレクトリにある NetNfpProvider.html ファイルを参照してください。シミュレーターを起動すると、近接通信アプリがフォアグラウンドで実行されている間、シミュレーターはバックグラウンドで実行されます。タップ シミュレーションが動作するには、アプリがフォアグラウンドに存在している必要があります。

 

要約と次のステップ

このチュートリアルでは、タップ ジェスチャまたはワイヤレス参照を使ってデバイスを接続するアプリを作りました。

さらに、タップ ジェスチャを使って、メッセージの発行と受信登録を行うこともできます。例については、「クイック スタート: タップを使ったメッセージの発行と購読」をご覧ください。

関連トピック

近接通信を使った開発のガイドライン

近接通信とタップのサポート

アプリの近接通信のテストとトラブルシューティング

Windows.Networking.Proximity namespace

サンプル

近接通信のサンプル