Phone Pairing Server sample (.NET)

Overview

This sample is the .NET server for the Phone Pairing scenario. It demonstrates a simple device-pairing flow: a mobile client must pair with the server once using a short code shown on the server, after which it is remembered and can log in automatically on subsequent connections.

The sample contains the server application only — it is meant to be used together with the iOS or Android Phone Pairing clients, which discover it on the network via ZeroConf/Bonjour.

Architecture

The server hosts a single PairingService over an IpHttpServerChannel with a BinMessage. The channel port is set to 0, so the OS assigns a free port and the server advertises itself through ZeroConfRegistration — the mobile client finds the server by service type rather than by a fixed address.

Two helper classes carry the pairing logic:

  • PairingStatusTracker — a thread-safe class that generates the random 4-digit pairing code and tracks its 60-second expiration.
  • ApprovedClientsStorage — a thread-safe class that persists the list of already-paired clients (by ClientID) in an ApprovedClients.lst text file next to the executable. Delete that file to reset the pairing state.

Getting started

  • Compile and run the application.
  • Make sure a ZeroConf facility (Bonjour) is running so the server is discoverable by the mobile client.
  • When a client attempts to pair, the server displays a random 4-digit code valid for 60 seconds. Enter that code on the client to complete pairing.
  • Once paired, the client's ClientID is stored and it logs in automatically next time. Only one client can pair at a time.

Examine the code

The pairing service

PairingService exposes two operations. LoginAttempt is called first: if the client is already known it logs in immediately; otherwise it starts a pairing sequence and shows a code on the server (unless another pairing is already in progress):

public virtual int LoginAttempt(System.Guid ClientGuid)
{
    if (ApprovedClientsStorage.IsClientKnown(ClientGuid))
    {
        Session["OK"] = true;
        return (int)PairingStatus.Successfull;
    }

    if (PairingStatusTracker.InitiatePairing() > 0)
    {
        MainForm.DisplayPairingCode(PairingStatusTracker.Code);
        return (int)PairingStatus.PairingRequired;
    }
    return (int)PairingStatus.PairingBusy;
}

ConfirmCode validates the code the user typed on the client. On success the client is remembered and its session is marked as authenticated:

public virtual bool ConfirmCode(string Code, System.Guid ClientGuid)
{
    bool res = PairingStatusTracker.Code.ToString().Equals(Code, StringComparison.Ordinal);
    if (res)
    {
        ApprovedClientsStorage.AddClient(ClientGuid);
        Session["OK"] = true;
    }
    PairingStatusTracker.CancelPairing();
    return res;
}

The pairing state (the 4-digit code, its validity window, and the "busy" flag) lives in PairingStatusTracker, while ApprovedClientsStorage reads and writes the ApprovedClients.lst file in a thread-safe way so it can be called from service methods on any worker thread.

Concepts Covered

See Also