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:
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
//???
}
} |
Retourner une List<T> ou un Objet o en WCF Duplex (Callback)
Voici la solution:
Code:
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.