Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

How to : Une petite application client / serveur avec WCF

Ce petit article a pour but de donner les étapes importantes pour écrire le squelette d'une application WCF client / serveur, avec un DuplexChannel, c'est à dire que le serveur peut appeler des méthodes sur le client (et pas seulement l'inverse). Avec les DuplexChannel, il devient facile d'écrire un programme client / serveur qui aurait nécessité autrefois d'aller chercher dans les Sockets.

Définir les contrats

Comme vous le savez surement, WCF est basé sur un système de contrats. Nous allons donc commencer par définir ces contrats dans un assembly qui sera réutilisé à la fois dans le client et dans le serveur. Commencez donc par créer une bibliothèque de classes qui contient le contrat du serveur, et le contrat du callback (tous deux sont des interfaces).

[ServiceContract(CallbackContract = typeof(IClient))]
public interface IServer
{
    [
OperationContract]
    bool Login(string user, string password);
    [
OperationContract]
    bool Say(string text);
}

[
ServiceContract()]
public interface IClient
{
    [
OperationContract]
    void ReceiveMessage(string message);
}

Si vous décidez d'utiliser des DataContract, c'est dans cet assembly qu'il faut les définir.

N'oubliez pas d'ajouter System.ServiceModel en référence du projet, sinon les attributs ServiceContract n'existeront pas.

Ecrire le serveur

Il faut maintenant fournir une implémentation de ce service (coté serveur). Nous allons prendre l'exemple d'un serveur console, mais rien ne vous empêche de le faire sous la forme d'un service Windows, ou d'une application WinForms par exemple.

Commencez par ajouter la référence au projet précédent, et à System.ServiceModel.

Nous allons déjà écrire l'implémentation du service. Il suffit pour cela de créer une classe qui implémente l'interface IServer, définie dans le 1er assembly.

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant, InstanceContextMode = InstanceContextMode.PerSession)]
public class FxComServer : IServer
{
    private string login;
    private IClient client;

    public bool Login(string user, string password)
    {
        login = user;
        client =
OperationContext.Current.GetCallbackChannel<IClient>();
        return true;
    }

    public bool Say(string text)
    {
        client.ReceiveMessage(login +
" said " + text);
        return true;
    }
}

Il ne faut pas oublier l'attribut ServiceBehavior. ConcurrencyMode indique la façon dont les threads de WCF seront gérés. Reentrant est un bon compromis, mais vous pouvez aller jeter un coup d'oeil sur MSDN à propos de Single et Multiple si vous avez d'autres besoins. Il peut aussi être utile de changer la valeur de InstanceContextMode selon si vous voulez gérer les sessions ou non.

Comme pour le client, si votre serveur est basé sur une application WinForms ou WPF, n'oubliez pas de mettre false à UseSynchronizationContext dans cet attribut.

Vous pouvez noter l'utilisation de la méthode GetCallbackChannel qui permet d'obtenir une instance d'un objet IClient par lequel vous pouvez appeler des méthodes du client. C'est de cette façon que vous pouvez appeler des méthodes du callback.

Il faut ensuite écrire un petit bout de code qui vous permettra de lancer le serveur et le stopper. Le voici :

internal static class Host
{
    internal static ServiceHost myServiceHost = null;

    internal static void StartService()
    {
        //Instantiate new ServiceHost
        myServiceHost = new ServiceHost(typeof(FxCommunicatorServer.FxComServer));
        //Open myServiceHost
        myServiceHost.Open();
    }

    internal static void StopService()
    {
        //Call StopService from your shutdown logic (i.e. dispose method)
        if (myServiceHost.State != CommunicationState.Closed)
            myServiceHost.Close();
    }
}

Cette classe à copier / coller, permet de lancer et stopper le serveur. Il suffit juste de changer le nom de la classe qui correspond à votre implémentation du service.

Tout le code du serveur est maintenant en place. Il ne reste plus que la touche finale : définir les EndPoints. Le plus pratique est de faire cela dans le fichier App.config. Ajoutez donc le fichier App.config à votre projet, et définissez des EndPoints de la façon suivante :

<?xml version="1.0" encoding="utf-8" ?>
<
configuration
>
    <
system.serviceModel
>
        <
services
>
            <
service name="FxCommunicatorServer.FxComServer"
>
                <
endpoint contract="FxCommunicatorService.IServer" binding="netTcpBinding" address="net.tcp://localhost:1303"
/>
                <
endpoint contract="FxCommunicatorService.IServer" binding="wsDualHttpBinding" address="http://localhost:80"
/>
            </
service
>
        </
services
>
    </
system.serviceModel
>
</
configuration>

Il suffit d'ajouter autant d'élément endpoint que vous voulez d'EndPoint pour votre serveur. Indiquez dans contract le contrat implémenté. Binding est un binding prédéfini dans WCF, mais attention, tous ne supportent pas le DuplexChannel. netTcpBinding (basé directement sur TCP donc relativement performant) et wsDualHttpBinding (basé sur HTTP donc mois performant mais plus interopérable) gèrent tous deux le DuplexChannel.

Le serveur est maintenant terminé. Il suffit juste d'appeler la méthode StartService et le tour est joué.

Ecrire le client

Pour le client, nous allons utiliser une application WinForms, mais une application WPF aurait très bien fait l'affaire.

Déjà, ajoutez le premier projet et System.ServiceModel en référence.

Ensuite, comme il s'agit d'un service qui utilise le DuplexChannel, le client doit avoir une classe qui implémente IClient (dans notre cas). C'est cette classe qui recevra les callbacks. Il est tout à fait possible que cette classe soit une Form :

[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant, UseSynchronizationContext = false)]
public partial class Form1 : Form,
IClient
{

    // [...]

    public void ReceiveMessage(string
message)
    {
        MessageBox
.Show(message);
    }
}

ConcurrencyMode permet d'éviter les deadlocks, comme pour le serveur. UseSynchronizationContext = false est indispensable lorsque l'application cliente est une application WinForms ou WPF. Sinon, l'application se bloquera au moindre appel du callback.

Pour terminer, il faut créer une instance du proxy vers le service :

IServer service;

private void button1_Click(object sender, EventArgs
e)
{
    service =
DuplexChannelFactory<IServer>.CreateChannel(this, new NetTcpBinding(), new EndpointAddress("net.tcp://localhost:1303"
));
}

Le premier objet en argument de CreateChannel est l'objet qui recevra les callbacks. Il doit donc implémenter IClient, dans notre cas c'est la Form elle même, c'est pour ça que c'est this. Le second correspond au Binding utilisé et le 3e à l'adresse de l'EndPoint.

Voilà, le tour est joué. Il ne reste plus qu'à appeller des méthodes du service depuis le client :

private void button2_Click(object sender, EventArgs e)
{
    service.Login(
"RaptorXP", "");
    service.Say(
"Hello");
}

Et voilà...

Bien sur, il y a beaucoup d'autres moyens de créer une application client / serveur (sans utiliser App.config par exemple), mais dans tous les cas, WCF permet un gain de temps considérable pour le développeur.

Pour finir, voici quelques liens utiles :

Publié dimanche 21 janvier 2007 11:31 par RaptorXP
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :

Commentaires

# re: How to : Une petite application client / serveur avec WCF

c'est quoi un endpoint?

dimanche 21 janvier 2007 21:33 by wizad

# re: How to : Une petite application client / serveur avec WCF

C'est la combinaison de :

- l'adresse à laquelle on peut joindre le service

- le binding utilisé par le service

- le contrat implémenté par le service

Il peut y en avoir plusieurs par service, comme dans cet article.

dimanche 21 janvier 2007 21:57 by RaptorXP

# re: How to : Une petite application client / serveur avec WCF

Simple, clair, efficace ! Bravo pour cet article !

lundi 22 janvier 2007 11:21 by minsou

# re: How to : Une petite application client / serveur avec WCF

j'ai essayer ton exemple vraiment trés bien aucun problème avec. Néammoins en essayant d'appronfondir la chose, je me trouve bloqué. Je ne comprend pas la gestion des clients au niveau du serveur.

Ce que j'ai fait : (sur le client) button1 passe aussi le service.login

(le serveur) renvoi Bonjour "toto"

(le client1) le button2 service.say(hello)

(le serveur) ==&gt; ici je souhaiterai que le message du client soit renvoyé à tous les client.

(le client2 qui était déja connecté) reçois un message "Client1 say : hello"

Mon problème se situe au niveau du passage du message du premier client aux autres.

lundi 22 janvier 2007 18:03 by wizad

# re: How to : Une petite application client / serveur avec WCF

Merci minsou :)

Wizad, en bref : Il faut que tu utilises un objet singleton qui a un moyen de répondre à chaque client connecté.

Je te propose de jeter un coup d'oeuil à cet exemple : http://wcf.netfx3.com/files/folders/distributed_applications/entry3220.aspx

J'écrirai peut être un article là dessus !

Bon courage ;)

mardi 23 janvier 2007 20:29 by RaptorXP
Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- Merci par Blog de Jérémy Jeanson le 10-01-2019, 20:47

- Office 365: Script PowerShell pour auditer l’usage des Office Groups de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 11:02

- Office 365: Script PowerShell pour auditer l’usage de Microsoft Teams de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 10:39

- Office 365: Script PowerShell pour auditer l’usage de OneDrive for Business de votre tenant par Blog Technique de Romelard Fabrice le 04-25-2019, 15:13

- Office 365: Script PowerShell pour auditer l’usage de SharePoint Online de votre tenant par Blog Technique de Romelard Fabrice le 02-27-2019, 13:39

- Office 365: Script PowerShell pour auditer l’usage d’Exchange Online de votre tenant par Blog Technique de Romelard Fabrice le 02-25-2019, 15:07

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Stream Portal par Blog Technique de Romelard Fabrice le 02-21-2019, 17:56

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Video Portal par Blog Technique de Romelard Fabrice le 02-18-2019, 18:56

- Office 365: Script PowerShell pour extraire les Audit Log basés sur des filtres fournis par Blog Technique de Romelard Fabrice le 01-28-2019, 16:13

- SharePoint Online: Script PowerShell pour désactiver l’Option IRM des sites SPO non autorisés par Blog Technique de Romelard Fabrice le 12-14-2018, 13:01