Introduction

Une des grandes nouveautés de Silverlight 3 est de pouvoir développer des applications qui vont s'exécuter directement depuis le bureau de l'utilisateur (hors du navigateur), comme pour une application normale.

Il peut donc arriver que lorsqu'une application SL3 s'exécute, l'utilisateur soit hors ligne. Cela peut être problématique si l'on veut par exemple accéder à un serveur pour y récupérer ou mettre à jour des informations.

Il nous faut donc pouvoir détecter et réagir à ce cas de figure. C'est exactement ce que propose la nouvelle API de notification de changement de la connexion réseau introduite avec Silverlight 3 que nous allons découvrir au cours de cet article.

L'application de démonstration est disponible en ligne ici.

I. La connexion réseau

Gérer le mode hors ligne au sein d'une application n'est pas chose aisée. De nombreux facteurs sont à prendre en compte et qui peuvent influer sur la détection d'une connexion réseau.

Le fait qu'une carte réseau indique une connexion réseau ne signifie pas que vous ayez effectivement accès à un réseau. En effet, une carte réseau reliée à un câble, lui-même branché à un hub ne menant nulle part indiquera quand même la présence d'une connexion réseau !

Des problèmes de système d'exploitation, de matériel, de drivers peuvent empêcher de détecter une connexion réseau.

L'utilisation de PC virtuels (bien connus des développeurs) est aussi sources de complication. Ceux-ci possèdent une carte réseau virtuelle qui peut isoler votre application du fait que la carte physique de la machine hôte puisse ne pas détecter de connexion.

Vous pouvez être confronté au problème du cybercafé. Imaginez-vous à la terrasse d'un cybercafé avec votre ordinateur portable connecté au réseau Wifi. Que va-t-il se passer si vous tentez d'ouvrir votre navigateur pour visualiser un site web ? Vous allez recevoir en retour une page web provenant du proxy du cybercafé vous invitant à payer ou entrer un code afin d'avoir accès à internet. L'important à remarquer ici est que vous ne recevrez pas une erreur (statut http 404) mais une bonne réponse (pas celle attendue, mais bonne au sens de son statut http 200). Il en sera de même pour une application Silverlight : la carte réseau indiquera une connexion, la requête http n'indiquera pas d'erreur, mais la réponse obtenue ne sera pas celle attendue !

Enfin, même en ayant une connexion réseau et un accès à votre serveur, il se peut que l'utilisateur ne souhaite quand même pas que votre application se connecte !


Ainsi, comment donc savoir si l'on est vraiment en ligne ? Pour cela nous devons pouvoir répondre par l'affirmative aux deux questions suivantes :

  • Peut-on accéder à notre serveur ?
  • A-t-on validé la réponse reçue ?

La façon dont votre application va répondre à ces questions dépend entièrement de vous, pas de Microsoft. C'est donc à vous, en tant que développeur d'écrire le code permettant de vérifier si votre application est en ligne ou non.

Par contre, L'API que Microsoft propose va vous permettre de savoir QUAND vous pouvez essayer de déterminer si vous êtes en ligne ou non.

L'espace de nom System.Net.NetworkInformation propose deux nouvelles classes, NetworkChange et NetworkInterface dont vous pouvez voir le diagramme ci-dessous :

NetworkInformation.png


La méthode GetIsNetworkAvailable indique si une connexion réseau est disponible. Attention, comme nous l'avons vu plus haut, une carte réseau reliée à un câble, lui-même branché à un hub ne menant nulle part indiquera quand même la présence d'une connexion réseau. Par contre, si la méthode renvoie faux, vous êtes sûr de ne pas avoir de connexion réseau disponible et il n'est donc pas utile de vérifier l'accès à votre serveur.

La classe NetworkChange contient l'évènement NetworkAddressChanged auquel vous pouvez vous abonner afin d'être notifié à chaque changement d'adresse IP d'une interface réseau. Pourquoi l'adresse IP ? Parce que quand vous branchez ou débranchez un câble réseau, activez ou désactivez le Wifi de votre ordinateur portable, l'adresse IP change. C'est donc un bon indicateur pour notifier un changement de la connectivité réseau. Notez bien que cet évènement indique un changement d'adresse IP, pas le fait qu'une connexion réseau soit disponible ou non !

Ces deux classes s'utilisent ensemble de la façon suivante :

  • On s'abonne à l'évènement NetworkAddressChanged
  • Lorsque l'évènement survient, on vérifie la disponibilité de la connexion via la méthode GetIsNetworkAvailable
  • Si la méthode renvoie faux alors nous sommes vraiment hors ligne. Si elle renvoie vrai alors nous pouvons vérifier (par notre propre code) si l'on est vraiment en ligne, c'est-à-dire, si nous avons bien accès à notre serveur.

Voici un exemple de code correspondant à cette démarche :

 
Sélectionnez
// Exécuté au démarrage de l'application
private void SetupNetworkChange()
{
     // On vérifie si une connexion réseau est disponible
      if (NetworkInterface.GetIsNetworkAvailable())
      {
          // Ici on peut vérifier l'accès à notre serveur
      }
      else
      {
          // Ici on est vraiment hors ligne dès le démarrage de l'application!
      }

    // On s'abonne à la notification de changement d'adresse IP
    NetworkChange.NetworkAddressChanged +=
        new NetworkAddressChangedEventHandler(OnNetworkChange);
}

// Exécuté à la notification de changement d'adresse IP
void OnNetworkChange(object sender, EventArgs e)
{
     // On vérifie si une connexion réseau est disponible
      if (NetworkInterface.GetIsNetworkAvailable())
      {
          // Ici on peut vérifier l'accès à notre serveur
      }
      else
      {
          // Ici on est vraiment hors ligne !
      }
}

II. Gérer le mode hors ligne

Il existe trois patterns que vous pouvez utiliser afin de gérer le mode hors ligne au sein de votre application. Ils ne sont pas exclusifs et vous pouvez bien sûr les combiner en fonction de vos besoins :

  • Demander à l'utilisateur
  • Avant de se connecter, valider
  • Continuellement valider les résultats

II-A. Demander à l'utilisateur

Ici c'est l'utilisateur qui contrôle la façon dont votre application gère sa connexion au serveur. On retrouve typiquement deux boutons dans votre application :

  • un bouton « réessayer » qui permet à l'utilisateur de forcer votre application à essayer de se reconnecter (à la manière du bouton rafraichir d'un navigateur).
  • un bouton « mode hors ligne » qui permet à l'utilisateur d'empêcher votre application d'essayer de se connecter. Utile par exemple pour une application sur téléphone mobile afin de l'empêcher de consommer tout le forfait internet de l'utilisateur !

II-B. Avant de se connecter, valider

Le deuxième pattern consiste à valider l'accès à notre serveur en se servant d'un fichier de test. Voici les différentes étapes à réaliser :

  • On dépose un fichier de test sur notre serveur
  • L'application télécharger et vérifie le contenu du fichier
  • Si l'accès au serveur échoue, alors l'application est vraiment hors ligne
  • On recommence l'opération à la prochaine notification de changement sur le réseau

Si l'on récupère un fichier du serveur mais qu'il ne s'agit pas du notre alors c'est qu'il s'agit du problème du cyber café.

Vous pouvez par exemple placer sur le serveur un fichier testconnexion.xml avec le contenu suivant :

 
Sélectionnez
<?xml version="1.0" encoding="utf-8" ?>
<testconnexion>
  <data>toto</data>
</testconnexion>


Afin de vérifier l'accès à votre serveur il suffit de tenter de télécharger le fichier et de vérifier que son contenu correspond à celui attendu :

 
Sélectionnez
private void CheckConnexionToServer()
{
    ConnectionStatus = ConnectionStatus.Connecting;
    string urlData = string.Format("{0}/../../testconnexion.xml", Application.Current.Host.Source);
    LoadDataRequest loadDataRequest = new LoadDataRequest(urlData);
    loadDataRequest.LoadDataRequestCompleted += loadDataRequest_LoadDataRequestCompleted;
    loadDataRequest.Execute();
}

void loadDataRequest_LoadDataRequestCompleted(object sender, LoadDataRequestCompletedEventArgs e)
{
    if (e.Response == "toto")
    {
        // c'est le bon fichier, on est en ligne
    }
    else
    {
        // pas la réponse attendue, pas d'accès au serveur
    }
}


La classe LoadDataRequest (dont vous pouvez voir le code dans les sources fournies en exemple) se charge de télécharger le fichier (en utilisant la classe WebClient) et de renvoyer le contenu de la balise data du fichier XML.

II-C. Continuellement valider les résultats

Il s'agit ici de vérifier à chaque fois les données reçues du serveur afin de s'assurer qu'elles sont valides.

  • On ne dispose pas de fichier test sur le serveur. Une validation est effectuée à chaque téléchargement.
  • Il ne s'agit pas seulement de vérifier les codes de statut http mais aussi la réponse en elle-même.
  • Si l'accès au serveur échoue, alors l'application est vraiment hors ligne

Si l'on récupère des données du serveur mais qu'il ne s'agit pas des nôtres, alors il est probable que nous soyons confrontés au problème du cyber café (vu précédemment).

III. Liens

Sources

Téléchargez les sources de la solution donnée en exemple.

Remerciements

J'adresse ici tous mes remerciements à l'équipe de rédaction de "developpez.com" pour le temps qu'ils ont bien voulu passer à la correction et à l'amélioration de cet article.

Contact

Si vous constatez une erreur dans le tutorial, dans les sources, dans la programmation ou pour toutes informations, n'hésitez pas à me contacter par le forum.