IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Returner une List<T> ou un Object o en WCF Duplex (Callback)


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Developpeur .Net
    Inscrit en
    Mai 2011
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Israël

    Informations professionnelles :
    Activité : Developpeur .Net
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2011
    Messages : 32
    Par défaut Returner une List<T> ou un Object o en WCF Duplex (Callback)
    Hello,

    J'ai un service WCF qui doit me retourner soit Un object Person ou une List<Person> selon ma requete.

    J'utilise un duplex pour envoyer mes requetes d'une class Sender et recevoir mes reponse dans une autre class Listner.

    Le probleme est que je suis tombe sur plusieurs examples mais surtout de chat ou messagerie qui ont des methods void.C'est qui est simple a implementer.

    j'apprecierai beacoup une aide sur comment retourner des objets ou collections avec le meme systeme.

    Merci.

    code sample:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    [ServiceContract(CallbackContract=(typeof(IMyServiceCallback)))]
    public interface IMyService
    {
     [OperationContract]
     Person GetPerson(int ID,int Age)
     
     [OperationContract]
     List<Person> GetAllPersons();
    }
     
    public interface IMyServiceCallback
    {
      [OperationContract(IsOneWay=true)]
     void OnGetPerson(int ID,int Age)
     
     [OperationContract(IsOneWay=true)]
     void OnGetAllPersons();
    }
    //.........
    public class MyService:IMyService
    {
     //DAL me connecte a ma Base des donnees
     private MyDAL dal = MyDAL.Dal;
            private static readonly List<ISIMServiceCallBack> callBacksList = new List<ISIMServiceCallBack>();
     public Person GetPerson(int ID,int Age)
     {
                      IMyServiceCallback callback = OperationContext.Current.GetCallbackChannel<IMyServiceCallback>();
                if (!callBacksList.Contains(callback))
                {
                    callBacksList.Add(callback);
                }
                callBacksList.ForEach(delegate(IMyServiceCallback call)
                {
                    if (((ICommunicationObject)call).State ==  CommunicationState.Opened)
                    {
                        call.OnGetPerson(ID,Age);
                    }
                    else
                    {
                        callBacksList.Remove(call);
                    }
                });
           //return ????
    }
     
     public List<Person> GetAllPersons()
     {
                   IMyServiceCallback callback = OperationContext.Current.GetCallbackChannel<IMyServiceCallback>();
                if (!callBacksList.Contains(callback))
                {
                    callBacksList.Add(callback);
                }
                callBacksList.ForEach(delegate(IMyServiceCallback call)
                {
                    if (((ICommunicationObject)call).State ==  CommunicationState.Opened)
                    {
                        call.OnGetAllPersons();
                    }
                    else
                    {
                        callBacksList.Remove(call);
                    }
                });
           //return ????
     }
    }
     
    //....
    public class Sender : IMyServiceCallback
    {
     private MyServiceClient client;
     public void Send()
     {
      InstanceContext context=new InstanceContext(this);
      client=new MyServiceClient(context);
      client.GetPerson(2,5);
      client.GetAllPersons();
     }
     
      public void OnGetPerson(int ID,int Age)
      {
        //Sans code
      }
     
     public void OnGetAllPersons()
     {
       //Sans code
     }
    }
     
    public class Listener: IMyServiceCallback
    {
     private MyServiceClient client;
     public void Receive()
     {
      InstanceContext context=new InstanceContext(this);
      client=new MyServiceClient(context);
      // ???
     }
     
      public void OnGetPerson(int ID,int Age)
      {
        //Recevoir ici mon objet Person p
       // ???
      }
     
     public void OnGetAllPersons()
     {
      //Recevoir ici ma List<Person> list 
      //???
     }
    }

  2. #2
    Rédacteur
    Avatar de Nathanael Marchand
    Homme Profil pro
    Expert .Net So@t
    Inscrit en
    Octobre 2008
    Messages
    3 615
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Expert .Net So@t
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 3 615
    Par défaut
    Pourquoi une communication duplex dans ce cas? Un simplex fonctionne très bien.

  3. #3
    Membre confirmé
    Homme Profil pro
    Developpeur .Net
    Inscrit en
    Mai 2011
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Israël

    Informations professionnelles :
    Activité : Developpeur .Net
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2011
    Messages : 32
    Par défaut
    J'en ai besoin (duplex) parceque mon systeme fonctionne comme ceci:
    - Lors du lancement de l'application ma class C1 qui contient ces deux methodes collecte des donnees et les retournes vers la class C2 qui les utilisera plus tard dans d'autres operations.
    - j'ai pour cela 3 services un pour charger les donnees ,un autre pour certaines operations qui sont requises par le UI et enfin le 3e qui est beaucoup plus business logic.
    -Les requetes venant de C1 et le UI sont canalisees vers C2 qui performe des calcules et renvoie les resultats au UI.
    c'est en fait un simulateur de traffic aerien .

  4. #4
    Rédacteur
    Avatar de Nathanael Marchand
    Homme Profil pro
    Expert .Net So@t
    Inscrit en
    Octobre 2008
    Messages
    3 615
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Expert .Net So@t
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 3 615
    Par défaut
    Ca répond pas du tout à ma question

    Pourquoi quand tu appelles GetEverybody() tu veux pas qu'il te retourne de suite le résultat? Y'a une raison?

  5. #5
    Membre confirmé
    Homme Profil pro
    Developpeur .Net
    Inscrit en
    Mai 2011
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Israël

    Informations professionnelles :
    Activité : Developpeur .Net
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2011
    Messages : 32
    Par défaut
    La raison est que la classe C1 n'a rien a faire avec les resultats (memes les requetes venant du UI) ils sont tous envoyes a la class C2 qui les utilise plutard pour creer d'autres objects et calculer les positions...

    C'est un des requirements du travail pour un peut mettre en valeur l'efficacite et la maintenabilite de WCF.
    Vous avez raison ca peut etre accompli avec un seul service mais supposons que je veuille ajouter ou ameliorer des methodes dans mon UI avec 3 service je n'ai pas besoin d'arreter tout mon systeme, seulement le service relatif au UI.
    Ou si un client a sa propre class C1 mais veut utiliser mon Calculateur la aussi il peut se passer de mon service S1.

    Merci.

  6. #6
    Rédacteur
    Avatar de Nathanael Marchand
    Homme Profil pro
    Expert .Net So@t
    Inscrit en
    Octobre 2008
    Messages
    3 615
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Expert .Net So@t
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 3 615
    Par défaut
    Je ne vois toujours pas l'interet du Duplex! Le decoupage doit se faire correctement au niveau de l'architecture du projet coté client et coté serveur (découpage en couche et/ou modules, découplage, utilisation de MEF par exemple.

  7. #7
    Membre confirmé
    Homme Profil pro
    Developpeur .Net
    Inscrit en
    Mai 2011
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Israël

    Informations professionnelles :
    Activité : Developpeur .Net
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2011
    Messages : 32
    Par défaut Retourner une List<T> ou un Objet o en WCF Duplex (Callback)
    Voici la solution:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
     
    [ServiceContract(CallbackContract=typeof(IMyServiceCallback),SessionMode=SessionMode.Allowed)]
    public interface IMyService
    {
     [OperationContract(IsOneWay=true)]
     void GetPerson(int ID,int Age)
     
     [OperationContract(IsOneWay=true)]
     void GetAllPersons();
     
    [OperationContract]
     bool OnGetPersons();
    }
     
    public interface IMyServiceCallback
    {
      [OperationContract(IsOneWay=true)]
     void OnGetPersonCallback(Person p)
     
     [OperationContract(IsOneWay=true)]
     void OnGetAllPersonsCallback(List<Person> list);
    }
    //.........
    public class MyService:IMyService
    {
     //DAL me connecte a ma Base des donnees
     private MyDAL dal = MyDAL.Dal;
            private static readonly List<ISIMServiceCallBack> callBacksList = new List<ISIMServiceCallBack>();
     public void GetPerson(int ID,int Age)
     {
                      IMyServiceCallback callback = OperationContext.Current.GetCallbackChannel<IMyServiceCallback>();
                if (!callBacksList.Contains(callback))
                {
                    callBacksList.Add(callback);
                }
                callBacksList.ForEach(delegate(IMyServiceCallback call)
                {
                    if (((ICommunicationObject)call).State ==  CommunicationState.Opened)
                    {
                         //Ici je passe ma mon objet Person que je recois de mon DAL 
                        //comme paramettre de ma method Callback 
                        call.OnGetPersonCallback(dal.GetPerson(ID,Age));
                    }
                    else
                    {
                        callBacksList.Remove(call);
                    }
                });
    }
     
     public void GetAllPersons()
     {
                   IMyServiceCallback callback = OperationContext.Current.GetCallbackChannel<IMyServiceCallback>();
                if (!callBacksList.Contains(callback))
                {
                    callBacksList.Add(callback);
                }
                callBacksList.ForEach(delegate(IMyServiceCallback call)
                {
                    if (((ICommunicationObject)call).State ==  CommunicationState.Opened)
                    {
                        //Ici je passe ma list<Person> que je recois de mon DAL 
                        //comme paramettre de ma method Callback 
                        call.OnGetAllPersonsCallback(dal.GetAllPersons());
                    }
                    else
                    {
                        callBacksList.Remove(call);
                    }
                });
     }
           //Cette method va me servir de trigger pour renvoyer mes reponse a ma
           //class Listener
             public bool OnGetPersons()
            {
                try
                {
                    IMyServiceCallback callback = OperationContext.Current.GetCallbackChannel<IMyServiceCallback >();
                    if (!callBacksList.Contains(callback))
                    {
                        callBacksList.Add(callback);
                    }
                    return true;
                }
                catch
                {
                    return false;
                }
            }
    }
     
    //....Request sender concurrencyMode doit etre Reentrant
    [CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]
    public class Sender : IMyServiceCallback
    {
     private MyServiceClient client;
     public void MyGetPerson()
     {
      InstanceContext context=new InstanceContext(this);
      client=new MyServiceClient(context);
      client.GetPerson(2,5);
     }
      public void MyGetAllPersons()
     {
      InstanceContext context=new InstanceContext(this);
      client=new MyServiceClient(context);
      client.GetAllPersons();
     }
      public void OnGetPersonCallback(Person p)
      {
        //Sans code
      }
     
     public void OnGetAllPersonsCallback(List<Person> list)
     {
       //Sans code
     }
    }
     
    //...Request Listener concurrencyMode doit etre Reetrant
    [CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]
    public class Listener: IMyServiceCallback
    {
     private MyServiceClient client;
     public Person person=null;
     public List<Person> personslist=null;
     
     public Listener()
     {
       person=new Person();
       personslist=new List<Person>();
     }
     public void Receive()
     {
      InstanceContext context=new InstanceContext(this);
      client=new MyServiceClient(context);
      Console.WriteLine("Waiting for Callback ...");
      client.OnGetPersons();
     }
     
      public void OnGetPersonCallback(Person p)
      {
         person=p;
      }
     
     public void OnGetAllPersonsCallback(List<Person> list)
     {
       personslist=list;
     }
    }
     
    //Implementation dans mon Main
        class Program
        {
            static void Main(string[] args)
            {
                Listener l= new Listener();
                l.Receive();
     
                Sender s= new Sender();
                s.MyGetPerson();
                s.MyGetAllPersons();
     
                //j'ai utilise Sleep pour permettre a mon main d'attendre 
                //le retour du Callback
                Thread.Sleep(5000);
                Person pr = p.person;
                List<Person> lst = p.personslist;
                Console.ReadLine();
            }
        }
    * Biensur ne pas oublier de placer l'app.config dans votre client (Host)
    * Binding: wsDualHttpBinding
    * Et ajour un endpoint (port different de celui de l'app.config du Service
    ex: http//:localhost:8732... http//:localhost:8730)

    J'espere que ca poura aider quelqu'un.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Return qui écrase une liste
    Par HaraKity dans le forum Général Python
    Réponses: 6
    Dernier message: 05/06/2014, 00h28
  2. Return une liste sur une autre classe
    Par b-yannick dans le forum C#
    Réponses: 1
    Dernier message: 11/06/2010, 20h37
  3. Réponses: 4
    Dernier message: 24/04/2003, 22h28
  4. Générer une liste
    Par pfredin dans le forum Langage SQL
    Réponses: 6
    Dernier message: 02/04/2003, 15h30
  5. tri d'une liste
    Par Guigui_ dans le forum Langage
    Réponses: 4
    Dernier message: 09/01/2003, 18h08

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo