简体   繁体   English

获取WCF回调以使用netTcpBinding

[英]Getting WCF callbacks to work with the netTcpBinding

I am having some issues getting callbacks working with my netTcpBinding WCF client/server. 我在使用netTcpBinding WCF客户端/服务器进行回调时遇到了一些问题。 Here is the code... any thoughts? 这是代码...任何想法?

Service Side 服务方

contract: 合同:

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

Here is the code that I am using to start the service 这是我用来启动服务的代码

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

Here is the App.Config 这是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 Side 客户端

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

Connecting and calling 连接和呼叫

 var instanceContext = new InstanceContext(new CallbackService());
 var service = new TurboValidateServiceClient(instanceContext);
 service.DoSomething();

App.Config 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>

I believe I have all the pieces needed. 我相信我需要所有的东西。 Google searching has led me down several different paths with no real result. 谷歌搜索让我走上了几条不同的道路而没有真正的结果。 I can see the service calling the callback, but my client is never getting it. 我可以看到服务调用回调,但我的客户端永远不会得到它。

Thanks in advance, I know this is a WCF 101 type question, but I am stumped at this point. 在此先感谢,我知道这是一个WCF 101类型的问题,但我很难过。

UPDATE UPDATE

On the client, I am getting this exception 在客户端,我得到这个例外

"The incoming message with action could not be processed because it is targeted at a request-reply operation, but cannot be replied to as the MessageId property is not set." “无法处理带有操作的传入消息,因为它的目标是请求 - 回复操作,但由于未设置MessageId属性,因此无法回复。”

followed by 其次是

"The channel received an unexpected input message with Action ' http://tempuri.org/IMyService/OnCallback ' while closing. You should only close your channel when you are not expecting any more input messages." “关闭时,频道收到了一条带有Action'http: //tempuri.org/IMyService/OnCallback '的意外输入消息。你应该只在不期待任何输入消息时关闭你的频道。”

It may be the problem is that the context is already closed by the time your timer fires. 可能问题在于,当计时器触发时,上下文已经关闭。

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

Try casting your callback to ICommunicationObject and checking the State property. 尝试将回调转换为ICommunicationObject并检查State属性。 If it isn't set to Open when you're attempting OnCallback , that's your problem. 如果在尝试OnCallback时没有设置为Open ,那就是你的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM