Mithilfe von NFC kann eine Verbindung zwischen zwei mobilen Geräten initiiert werden, die über Bluetooth oder WiFi weitergeführt wird. Diese Verbindung kann zum Austausch von beliebigen Daten genutzt werden. In diesem letzten Teil der Artikelserie wird dazu die Klasse PeerFinder vorgestellt, die zum Verbindungsaufbau verwendet wird und wie die weitere Kommunikation über Sockets abgewickelt werden kann.

Wie oben bereits genannt, wird NFC lediglich für einen Handshake zwischen den Geräten verwendet, die eine Verbindung miteinander aufbauen wollen. Die weitere Verbindung wird über Bluetooth oder WiFi weitergeführt. Für eine WiFi-Verbindung müssen sich beide Geräte im selben WLAN befinden und gegenseitig erreichen können. Eine Verbindung über Bluetooth ist deshalb wesentlich einfacher, da nur Bluetooth an beiden Geräten aktiviert sein muss.

1. Die Klasse PeerFinder

Zum Verbindungsaufbau wird die statische Klasse PeerFinder verwendet. Im ersten Schritt kann über die Eigenschaften AllowBluetooth und AllowInfrastructure festgelegt werden, ob Bluetooth, WiFi oder beides verwendet werden darf. Der PeerFinder wählt später eigenständig die beste verfügbare Methode aus.

Vor dem Starten des PeerFinders muss das Event TriggeredConnectionStateChanged registriert werden. Die Ergeignisbehandlung wird später dazu verwendet, um auf Verbindungsanfragen und Verbindungsänderungen zu reagieren. Über die statische Methode Start() kann die Suche nach anderen Peers gestartet werden.

1
2
3
4
5
6
7
8
9
10
11
var device = ProximityDevice.GetDefault();
if (device != null)
{
    PeerFinder.DisplayName = "Daniels Windows Phone";
    PeerFinder.AllowBluetooth = true;
    PeerFinder.AllowInfrastructure = true;

    PeerFinder.TriggeredConnectionStateChanged += PeerFinder_TriggeredConnectionStateChanged;

    PeerFinder.Start();
}

Das ProximityDevice wird im oberen Codeausschnitt nur benötigt, um die NFC-Unterstützung des Geräts zu überprüfen. Soll die Suche nach Peers beendet werden, kann die Methode Stop() des PeerFinders aufgerufen werden. Innerhalb des TriggeredConnectionStateChanged-Ereignisses kann nun auf die verschiedenen Zustände des PeerFinders reagiert werden. Folgende Zustände können auftreten:

  • Listening - Verbindung wird als Host eröffnet
  • Connecting - Verbindung zum Host wird hergestellt
  • PeerFound - Das Pairing über NFC war erfolgreich, die weitere Verbindung läuft über Bluetooth oder TCP/IP ab
  • Completed - Die Verbindung wurde hergestellt
  • Canceled - Verbindungsaufbau wurde abgebrochen
  • Failed - Fehler beim Verbindungsaufbau (Häufige Fehlerursache: Es kann keine Verbindung über das WiFi hergestellt werden oder Bluetooth ist nicht aktiviert)

Wenn die Verbindung hergestellt wurde, wird mit dem Übergabeparameter des Handlers ein StreamSocket mitgeliefert, über den mit dem anderen Gerät kommuniziert werden kann.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private void PeerFinder_TriggeredConnectionStateChanged(object sender, TriggeredConnectionStateChangedEventArgs args)
{
    if (args.State == TriggeredConnectState.Completed)
    {
        // Socket for sending and receiving messages
        var socket = args.Socket;

        // Get reader and writer for communication
        this.dataReader = new DataReader(socket.InputStream);
        this.dataWriter = new DataWriter(socket.OutputStream);

        // Start listening for messages
        this.ListenForIncomingMessage();
    }
}

Vom Socket kann daraufhin ein Input- und Output-Stream für eingehende und ausgehende Nachrichten abgefragt werden. Diese können über einen DataReader und DataWriter für das Empfangen und Senden von Nachrichten verwendet werden. Für den Empfang von Nachrichten wird eine Methode ListenForIncomingMessage angelegt.

2. Empfangen von Nachrichten

Das Empfangen von Nachrichten über den DataReader läuft hier nach einem festen Schema ab: Vor der eigentlichen Nachricht wird jeweils ein Integerwert als Header geschickt, der die Länge der Nachricht angibt. Somit muss zuerst die Länge der eingehenden Nachricht gelesen werden, daraufhin kann die Nachricht mit dem benötigten Datentyp empfangen werden (hier im Beispiel String).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
private async void ListenForIncomingMessage()
{
    try
    {
        // Read length
        await this.dataReader.LoadAsync(4);
        var messageLength = (uint)this.dataReader.ReadInt32();

        // Read data
        await this.dataReader.LoadAsync(messageLength);
        var message = this.dataReader.ReadString(messageLength);

        // Do something with the message
        // ...

        // Listen for next message
        this.ListenForIncomingMessage();
    }
    catch (Exception e)
    {
        this.CloseConnection();
    }
}

3. Senden von Nachrichten

Zum Senden einer Nachricht wird zuerst die Länge der Nachricht bestimmt und vor der eigentlichen Nachricht über den Socket gesendet. Die Nachricht ist im folgenden Beispiel wieder vom Typ String.

1
2
3
4
5
6
7
8
9
10
private async Task SendMessageAsync(string message)
{
    // Get the length of the message
    var messageLength = dataWriter.MeasureString(message);
    dataWriter.WriteInt32((int)messageLength);

    // Send the message
    var sentCommandSize = dataWriter.WriteString(message);
    await dataWriter.StoreAsync();
}

Die Klassen DataWriter und DataReader stellen für viele Datentypen eine Methode zum Senden bzw. Empfangen bereit. So auch für ByteArrays oder einen Buffer. Dadurch können beliebige Daten zwischen den Peers ausgetauscht werden.

4. Zusammenfassung

In diesem abschließenden Artikel der Serie wurde gezeigt, wie NFC zum Verbindungsaufbau zwischen zwei WindowsPhone-Geräten verwendet werden kann. Die Verbindung wird über Bluetooth oder WiFi weitergeführt und läuft über Sockets ab.

Durch die vielen in dieser Artikelserie vorgestellte Beispiele wurde bereits gezeigt, dass die Einsatzbereiche für NFC sehr vielseitig sind. Den möglichen Anwendungsgebieten sind meist keine Grenzen gesetzt. NFC ist eine spannende Technologie, die in Zukunft immer mehr an Bedeutung gewinnen könnte. Das kommt jedoch ganz auf die Unterstützung der mobilen Plattformen und die Menge der Apps an, die NFC einsetzen.

Beispielprojekt: NFC Chat

Die oben gezeigten Codebeispiele sind in einem Beispielprojekt für Windows Phone enthalten. Das Projekt ist eine Chatanwendung, über die zwei Partner miteinander kommunizieren können.  Den Quellcode gibt es hier auf GitHub.