J'ai des problèmes pour que des rappels fonctionnent avec mon client / serveur WCF NetTCPBinding. Voici le code ... des pensées?
Côté service
Contrat:
using System.Runtime.Serialization;
using System.ServiceModel;
namespace API.Interface
{
[ServiceContract(CallbackContract = typeof(IServiceCallback))]
public interface IMyService
{
[OperationContract]
void DoSomething();
}
public interface IServiceCallback
{
[OperationContract(IsOneWay = true)]
void OnCallback();
}
}
service:
using System;
using System.Security.Cryptography.X509Certificates;
using System.ServiceModel;
using System.Timers;
using API.Interface;
namespace API.Service
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Reentrant)]
public class MyService : IMyService
{
public static IServiceCallback callback;
public static Timer Timer;
public void DoSomething()
{
Console.WriteLine("> Session opened at {0}", DateTime.Now);
callback = OperationContext.Current.GetCallbackChannel<IServiceCallback>();
Timer = new Timer(1000);
Timer.Elapsed += OnTimerElapsed;
Timer.Enabled = true;
}
void OnTimerElapsed(object sender, ElapsedEventArgs e)
{
callback.OnCallback();
}
}
}
Voici le code que j'utilise pour démarrer le service
var service = new MyService();
// Start up the WCF API
var service = new ServiceHost(turboService);
service.Open();
Voici l'application.config
<system.serviceModel>
<services>
<service name="API.Service.MyService">
<endpoint address="" binding="netTcpBinding" bindingConfiguration=""
contract="API.Interface.IMyService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexTcpBinding" bindingConfiguration=""
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8732/MyService/"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Côté client
Rappel
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using USBAutomationTester.ServiceReference;
namespace USBAutomationTester
{
[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant, UseSynchronizationContext = false)]
public class CallbackService : IMyServiceCallback
{
public void OnCallback()
{
Console.WriteLine("> Received callback at {0}", DateTime.Now);
}
}
}
Connexion et appel
var instanceContext = new InstanceContext(new CallbackService());
var service = new TurboValidateServiceClient(instanceContext);
service.DoSomething();
App.config
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_IMyService" />
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://localhost:8732/MyService/"
binding="netTcpBinding" bindingConfiguration="NetTcpBinding_ITurboValidateService"
contract="ServiceReference.IMyService"
name="NetTcpBinding_IMyService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
Je crois que j'ai toutes les pièces nécessaires. Google Searching m'a conduit à plusieurs chemins différents sans résultat réel. Je peux voir le service appeler le rappel, mais mon client ne l'obtient jamais.
Merci d'avance, je sais que c'est une question de type WCF 101, mais je suis perplexe à ce stade.
METTRE À JOUR
Sur le client, je reçois cette exception
"Le message entrant avec action n'a pas pu être traité car il est ciblé lors d'une opération de demande, mais ne peut pas être répondu car la propriété MessageID n'est pas définie."
suivie par
"Le canal a reçu un message d'entrée inattendu avec l'action 'http://tempuri.org/imyservice/oncallback«Pendant la fermeture. Vous ne devez fermer votre chaîne que lorsque vous n'attendez plus de messages d'entrée. "