문제

NetTCPBinding WCF 클라이언트/서버와 함께 콜백을하는 데 문제가 있습니다. 여기에 코드가 있습니다 ... 어떤 생각이 있습니까?

서비스 측

계약:

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

서비스:

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

서비스를 시작하기 위해 사용하는 코드는 다음과 같습니다.

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

다음은 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>

고객 입장에서

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

연결 및 호출

 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>

나는 필요한 모든 조각이 있다고 생각합니다. Google 검색으로 인해 실제 결과가없는 몇 가지 다른 경로가 줄었습니다. 서비스가 콜백을 호출하는 것을 볼 수 있지만 내 클라이언트는 결코 그것을 얻지 못합니다.

미리 감사드립니다. 저는 이것이 WCF 101 유형 질문이라는 것을 알고 있지만이 시점에서 혼란스러워합니다.

업데이트

클라이언트에서는이 예외를 얻고 있습니다

"조치가 포함 된 들어오는 메시지는 요청-보고서 작업을 목표로하기 때문에 처리 할 수는 없지만 MessageID 속성이 설정되지 않았기 때문에 응답 할 수 없습니다."

그 뒤에

"채널은 동작이있는 예상치 못한 입력 메시지를 받았습니다."http://tempuri.org/imyservice/oncallback'폐쇄하는 동안. 더 이상 입력 메시지를 기대하지 않을 때만 채널을 닫아야합니다. "

도움이 되었습니까?

해결책

문제는 타이머가 발사 될 때 컨텍스트가 이미 닫혀 있다는 것입니다.

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

콜백을 캐스팅 해보세요 ICommunicationObject 그리고 확인 State 재산. 설정되지 않은 경우 Open 당신이 시도 할 때 OnCallback, 그게 당신의 문제입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top