Frage

Ich habe einige Probleme, um Rückrufe zu erhalten, die mit meinem NettCPBinding -WCF -Client/Server arbeiten. Hier ist der Code ... irgendwelche Gedanken?

Serviceseite

Vertrag:

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();
        }
    }
}

Hier ist der Code, den ich verwende, um den Dienst zu starten

        var service = new MyService();
        // Start up the WCF API
        var service = new ServiceHost(turboService);
        service.Open();

Hier ist die App.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>

Client -Seite

Callbackservice

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);
        }
    }
}

Verbinden und Anrufe

 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>

Ich glaube, ich habe alle benötigten Stücke. Google Searching hat mich ohne wirkliches Ergebnis mehrere verschiedene Wege geführt. Ich kann sehen, dass der Service den Rückruf ruft, aber mein Kunde bekommt ihn nie.

Vielen Dank im Voraus, ich weiß, dass dies eine WCF 101 -Frage ist, aber ich bin an dieser Stelle ratlos.

AKTUALISIEREN

Auf dem Kunden bekomme ich diese Ausnahme

"Die eingehende Nachricht mit Aktion konnte nicht verarbeitet werden, da sie auf einen Request-Refy-Betrieb ausgerichtet ist, aber nicht beantwortet werden kann, da die MessageID-Eigenschaft nicht festgelegt ist."

gefolgt von

"Der Kanal erhielt eine unerwartete Eingabenachricht mit Aktion 'http://tempuri.org/imyService/oncallback'Während des Schließens. Sie sollten Ihren Kanal nur schließen, wenn Sie keine weiteren Eingabemeldungen erwarten. "

War es hilfreich?

Lösung

Das Problem kann sein, dass der Kontext bereits geschlossen ist, wenn Ihr Timer feuert.

    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();
    }

Versuchen Sie, Ihren Rückruf anzusetzen ICommunicationObject und überprüfe State Eigentum. Wenn es nicht auf eingestellt ist Open Wenn Sie versuchen OnCallback, das ist dein Problem.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top