Programmation C sharp/Exécution distante

Un livre de Wikibooks.

Puzzle.svg
Ébauche

Cette page est considérée comme une ébauche à compléter. Si vous possédez quelques connaissances sur le sujet, vous pouvez les partager en éditant dès à présent cette page (en cliquant sur le lien « modifier »).

Ressources suggérées : Programmation C sharp/Bibliographie et liens

Programmation C#
Programmation C#
Sommaire
Le langage
Programmation avancée
API .Net
Ressources
Modifier ce modèle

Une application .NET peut être un service distant et peut s'exécuter comme :

Sections

[modifier] Serveur RPC

[modifier] Serveur Remoting

À l'aide de la librairie System.Runtime.Remoting à placer dans l'application servante et cliente, celles-ci peuvent partager une classe par Marshaling suivant un canal Http, Ipc ou Tcp.

Le remoting utilise les échanges RPC.

Dans cette solution :

  1. INTERFACE : IRemoteMath est une librairie de classe
  2. SERVER : RemoteServer est une application console
  3. CLIENT : RemoteClient est une application console

[modifier] L'interface partagée

Une interface IOperations comprenant un prototype d'addition.

namespace IRemoteMath
{
    public interface IOperations
    {
        int Addition(int a, int b);
    }
}

[modifier] Le serveur

Le serveur est l'application qui distribue ses services. Pour qu'elle déserve à distance, il lui faut :

  • Dans ses références :
  1. System.Runtime.Remoting
  2. Le namespace d'IRemoteMath
  • Implémenter IOperations

[modifier] Implémenter IOperations

La classe à servir doit faire partie du service distributeur ici RemoteServer

namespace RemoteServer
{
    public class RemoteOperations : MarshalByRefObject, IRemoteMath.IOperations
    {
        // l'objet aura une durée de vie illimitée
        public override object InitializeLifetimeService()
        {
            return null;
        }
 
        // cette méthode sera servie
        public int Addition(int a, int b)
        {
            Console.WriteLine(String.Format("> Addition() : a={0}, b={1}", a, b));
            return a + b;
        }
    }
}

MarshalByRefObject signifie que RemoteOperations fera l'objet d'un marshaling.

[modifier] Configurer RemoteMain

Pour écouter les appels, le serveur doit créer un canal d'écoute sur un port et enregistrer le service à distribuer.

using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
 
namespace RemoteServer
{
    class RemoteMain
    {
        [STAThread]
        static void Main(string[] args)
        {
            try
            {
                // Création du canal sur le port 1050
                TcpChannel channel = new TcpChannel(1050);
                // Enregistrement du canal
                ChannelServices.RegisterChannel(channel);
                // Distribution de l'objet en mode singleton
                RemotingConfiguration.RegisterWellKnownServiceType(
                    typeof(RemoteOperations),
                    "RemoteOperations",
                    WellKnownObjectMode.Singleton);
 
                Console.WriteLine("Serveur démarré");
                Console.ReadLine();
            }
            catch
            {
                Console.WriteLine("Erreur au démarrage");
                Console.ReadLine();
            }
        }
    }
}
  1. [STAThread] au point d'entrée instruit le main comme "appartement" pour cloisonner les traitements au partage de ses ressources.
  2. RemotingConfiguration.RegisterWellKnownServiceType enregistre RemoteOperations dans ses services
  3. Le canal est ici en TCP

[modifier] Le client

Le client appelle les services. Pour qu'elle soit servie, il lui faut :

  • Dans ses références :
  1. System.Runtime.Remoting
  2. Le namespace d'IRemoteMath
using System;
using System.Text;
 
// Remoting
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
 
namespace RemoteClient
{
    class RemoteTestClient
    {
	// préparation de l'objet distribué
	private IRemoteMath.IOperations remoteOperation;
 
	public RemoteTestClient()
	{
            try
            {	
		// init channel - facultatif
                // TcpChannel channel = new TcpChannel();
                // ChannelServices.RegisterChannel(channel);
		// init IOperations < RemoteServer.RemoteOperations
                this.remoteOperation = (IRemoteMath.IOperations)Activator.GetObject(
                    typeof(IRemoteMath.IOperations),
                    "tcp://localhost:1050/RemoteOperations");
            }
            catch { 
                Console.WriteLine("Erreur de connexion"); 
            }
	}
 
	public void RemoteAddition(int a, int b)
	{
	    try
            {
                if (this.remoteOperation != null)
                {
                    Console.WriteLine("Résultat : " + this.remoteOperation.Addition(a, b).ToString());
                }
            }
            catch 
	    {
		Console.WriteLine("Erreur à l'appel");
	    }
	}
 
	[STAThread]
        static void Main()
        {
            RemoteTestClient Client = new RemoteTestClient();
	    Client.RemoteAddition(15, 20);
 
	    System.Threading.Thread.Sleep(5000);
        }
    }
}
  1. [STAThread] indique qu'on est dans le même type de cloisonnement des threads que pour server.
  2. remoteOperation dépile la classe reçu par TCP permettant l'utilisation de ses propriétés.

[modifier] Application

  1. Pour effectuer le test, il faut compiler les trois projets IRemoteMath,RemoteServer,RemoteClient
  2. Executer RemoteServer.exe avant RemoteClient.exe

Le résultat du client devrait être :

Résultat : 35

Le message du serveur devrait être :

> Addition() : a=15, b=20 

[modifier] Serveur de pipes

[modifier] Serveur de queue