WPF上的多WCF回调接口

WPF上的多WCF回调接口,wcf,Wcf,我必须传达2 WPF应用程序。 为了进行通信,我正在使用本地计算机上运行的WCF windows服务 当其中一个调用服务上的一个方法时,服务将回调另一个方法。只有一个回调接口,所有方法都写在其中。但是,2个WPF应用程序使用的回调方法不同。因此,我被迫实现未使用的方法 所以,我试图找到是否可以在服务上设置两个不同的、独立的回调接口,但我做不到。有什么办法吗 更新 我的示例代码: IDeviceCallBack public interface ITestCallBack1 { [Oper

我必须传达2 WPF应用程序。 为了进行通信,我正在使用本地计算机上运行的WCF windows服务

当其中一个调用服务上的一个方法时,服务将回调另一个方法。只有一个回调接口,所有方法都写在其中。但是,2个WPF应用程序使用的回调方法不同。因此,我被迫实现未使用的方法

所以,我试图找到是否可以在服务上设置两个不同的、独立的回调接口,但我做不到。有什么办法吗

更新

我的示例代码:

IDeviceCallBack

public interface ITestCallBack1
{
    [OperationContract(IsOneWay = true)]
    void Test1();
}

public interface ITestCallBack2
{
    [OperationContract(IsOneWay = true)]
    void Test2();
}

public interface IDeviceCallback : ITestCallBack1, ITestCallBack2
{ }
创意

[ServiceContract(CallbackContract = typeof(ITestCallBack1))]
public interface ITestContract1
{ }

[ServiceContract(CallbackContract = typeof(ITestCallBack2))]
public interface ITestContract2
{ }


[ServiceContract(CallbackContract = typeof(IDeviceCallback))]
public interface IDevice : ITestContract1, ITestContract2
{
    [OperationContract]
    bool Subscribe();

    [OperationContract]
    bool Unsubscribe();
}
我想要的是: WPF1

WPF2


我不完全清楚你在这里的要求,但我会尝试帮助你无论如何

因此,在WCF中,每个服务只能有一个回调接口,这意味着您将需要两个服务。不过,您可以执行一些继承,这样就不必在服务器上复制任何内容。下面是一个例子,我希望解释如何做到这一点

// A base interface for both services that contains the common methods
[ServiceContract]
public interface ITestService
{
    [OperationContract]
    bool Subscribe();

    [OperationContract]
    bool Unsubscribe();
}

// Service interface for service 1, using callback 1
[ServiceContract(CallbackContract = typeof(ITestCallBack1))]
public interface ITestContract1 : ITestService
{
}

// Callback interface for service 1
public interface ITestCallBack1
{
    [OperationContract(IsOneWay = true)]
    void Test1();
}

// Service interface for service 2, using callback 2
[ServiceContract(CallbackContract = typeof(ITestCallBack2))]
public interface ITestContract2 : ITestService
{
}

// Callback interface for service 2
public interface ITestCallBack2
{
    [OperationContract(IsOneWay = true)]
    void Test2();
}

// This is a base class that contains everything common to the two services
public abstract class TestServiceBase<T> : ITestService
{

    public bool Subscribe()
    {
        // Let's say that after subscribing we will wait for a bit
        // and call back (just an example)
        ThreadPool.QueueUserWorkItem(o =>
                                         {
                                             Thread.Sleep(5000);
                                             RaiseCallback((T) o);
                                         },
                                     OperationContext
                                         .Current
                                         .GetCallbackChannel<T>());
        return true;
    }

    public bool Unsubscribe()
    {
        // Do whatever you need here
        return true;
    }

    // abstract method to raise the callback because the method names
    // are different for the two callback interfaces - notice the overriding
    // method does not need to do anything except call the correctly named method
    protected abstract void RaiseCallback(T callback);
}

// Concrete implementation of TestService1 - you can see that it
// only does whatever is specific for it
public class TestService1 : TestServiceBase<ITestCallBack1>, ITestContract1
{
    // Notice I get the callback1 interface to call the client
    protected override void RaiseCallback(ITestCallBack1 callback)
    {
        callback.Test1();
    }
}

// Concrete implementation of TestService2 - you can see that it
// only does whatever is specific for it
public class TestService2 : TestServiceBase<ITestCallBack2>, ITestContract2
{
    // Notice I get the callback2 interface to call the client
    protected override void RaiseCallback(ITestCallBack2 callback)
    {
       callback.Test2();
    }
}   
//包含公共方法的两个服务的基本接口
[服务合同]
公共接口ITestService
{
[经营合同]
bool Subscribe();
[经营合同]
bool退订();
}
//服务1的服务接口,使用回调1
[ServiceContract(CallbackContract=typeof(ITestCallBack1))]
公共接口ITestContract1:ITestService
{
}
//服务1的回调接口
公共接口ITestCallBack1
{
[运营合同(IsOneWay=true)]
void Test1();
}
//服务2的服务接口,使用回调2
[ServiceContract(CallbackContract=typeof(ITestCallBack2))]
公共接口ITestContract2:ITestService
{
}
//服务2的回调接口
公共接口ITestCallBack2
{
[运营合同(IsOneWay=true)]
void Test2();
}
//这是一个基类,包含两个服务的所有公共内容
公共抽象类TestServiceBase:ITestService
{
公共bool Subscribe()
{
//假设订阅后我们会等待一段时间
//然后再打回来(只是一个例子)
ThreadPool.QueueUserWorkItem(o=>
{
睡眠(5000);
拉回((T)o);
},
操作上下文
现在的
.GetCallbackChannel());
返回true;
}
公共bool退订()
{
//你需要什么就做什么
返回true;
}
//因为方法名为
//对于这两个回调接口来说是不同的-请注意重写
//方法不需要执行任何操作,只需调用正确命名的方法
受保护的抽象空RaiseCallback(T回调);
}
//TestService1的具体实现——您可以看到
//只做特定的事情
公共类TestService1:TestServiceBase,ITestContract1
{
//注意,我使用callback1接口调用客户机
受保护的覆盖无效RaiseCallback(ITestCallBack1回调)
{
callback.Test1();
}
}
//TestService2的具体实现——您可以看到它
//只做特定的事情
公共类TestService2:TestServiceBase,ITestContract2
{
//注意,我使用callback2接口调用客户机
受保护的覆盖无效RaiseCallback(ITestCallBack2回调)
{
callback.Test2();
}
}   
以下是服务的配置:

<system.serviceModel>
  <services>
    <service name="Demo.TestService1" behaviorConfiguration="NetTcpServiceBehavior">
      <host>
        <baseAddresses>
          <add baseAddress="net.tcp://localhost:9999/TestService1"/>
        </baseAddresses>
      </host>
     <endpoint address="" binding="netTcpBinding" contract="Demo.ITestContract1" bindingConfiguration="NetTcpBindingConfiguration"/>
     <endpoint address="mex" binding="netTcpBinding" contract="IMetadataExchange" bindingConfiguration="MexBindingConfiguration"/>
    </service>
    <service name="Demo.TestService2" behaviorConfiguration="NetTcpServiceBehavior">
      <host>
        <baseAddresses>
          <add baseAddress="net.tcp://localhost:9999/TestService2"/>
        </baseAddresses>
      </host>
      <endpoint address="" binding="netTcpBinding" contract="Demo.ITestContract2" bindingConfiguration="NetTcpBindingConfiguration"/>
      <endpoint address="mex" binding="netTcpBinding" contract="IMetadataExchange" bindingConfiguration="MexBindingConfiguration"/>
    </service>
  </services>
  <bindings>
    <netTcpBinding>
      <binding name="NetTcpBindingConfiguration"
               maxConnections="5"
               portSharingEnabled="true">
        <security mode="None">
          <transport protectionLevel="None"/>      
        </security>
      </binding>
      <binding name="MexBindingConfiguration" portSharingEnabled="true">
        <security mode="None">
          <transport protectionLevel="None"/>    
        </security>
      </binding>
    </netTcpBinding>
  </bindings>
  <behaviors>
    <serviceBehaviors>
      <behavior name="NetTcpServiceBehavior">
        <serviceMetadata />
      </behavior>
    </serviceBehaviors>
  </behaviors>
</system.serviceModel>

然后在客户机上,您需要一个对您感兴趣的回调服务的引用(因此您的WPF1将引用/TestService1和WPF2/TestService2)


请注意,您可以将两个服务共有的所有逻辑放在TestServiceBase类中—它接受回调接口,以便调用它。实际上,您可能不需要这样做-我不知道在什么情况下您希望回拨到客户端

我认为服务只能有一个回拨接口。把你的服务一分为二怎么样?如果他们在做两种不同的概念性操作,那么无论如何可能更有意义。也许发布一段代码来展示你在做什么?@user1039947我发布了一段代码。你是对的,我应该。将会有这么多的信息,我不想这样。或者,有什么方法可以做到这一点吗?(除了私人IntPtr WndProc)谢谢@user1039947的帮助。我理解你的尝试,那太棒了。我还没有时间尝试代码,可能它会工作。但是,可能存在这样的情况:wpf1调用ITestContract1方法。然后,它首先发送回调ITestCallBack2,然后发送回调ITestCallBack1。(很快,contact1将发送callback1和callback2)。有可能吗?如果您有一个客户端需要处理两个不同的回调,那么我就在回调接口上有两个方法。
// A base interface for both services that contains the common methods
[ServiceContract]
public interface ITestService
{
    [OperationContract]
    bool Subscribe();

    [OperationContract]
    bool Unsubscribe();
}

// Service interface for service 1, using callback 1
[ServiceContract(CallbackContract = typeof(ITestCallBack1))]
public interface ITestContract1 : ITestService
{
}

// Callback interface for service 1
public interface ITestCallBack1
{
    [OperationContract(IsOneWay = true)]
    void Test1();
}

// Service interface for service 2, using callback 2
[ServiceContract(CallbackContract = typeof(ITestCallBack2))]
public interface ITestContract2 : ITestService
{
}

// Callback interface for service 2
public interface ITestCallBack2
{
    [OperationContract(IsOneWay = true)]
    void Test2();
}

// This is a base class that contains everything common to the two services
public abstract class TestServiceBase<T> : ITestService
{

    public bool Subscribe()
    {
        // Let's say that after subscribing we will wait for a bit
        // and call back (just an example)
        ThreadPool.QueueUserWorkItem(o =>
                                         {
                                             Thread.Sleep(5000);
                                             RaiseCallback((T) o);
                                         },
                                     OperationContext
                                         .Current
                                         .GetCallbackChannel<T>());
        return true;
    }

    public bool Unsubscribe()
    {
        // Do whatever you need here
        return true;
    }

    // abstract method to raise the callback because the method names
    // are different for the two callback interfaces - notice the overriding
    // method does not need to do anything except call the correctly named method
    protected abstract void RaiseCallback(T callback);
}

// Concrete implementation of TestService1 - you can see that it
// only does whatever is specific for it
public class TestService1 : TestServiceBase<ITestCallBack1>, ITestContract1
{
    // Notice I get the callback1 interface to call the client
    protected override void RaiseCallback(ITestCallBack1 callback)
    {
        callback.Test1();
    }
}

// Concrete implementation of TestService2 - you can see that it
// only does whatever is specific for it
public class TestService2 : TestServiceBase<ITestCallBack2>, ITestContract2
{
    // Notice I get the callback2 interface to call the client
    protected override void RaiseCallback(ITestCallBack2 callback)
    {
       callback.Test2();
    }
}   
<system.serviceModel>
  <services>
    <service name="Demo.TestService1" behaviorConfiguration="NetTcpServiceBehavior">
      <host>
        <baseAddresses>
          <add baseAddress="net.tcp://localhost:9999/TestService1"/>
        </baseAddresses>
      </host>
     <endpoint address="" binding="netTcpBinding" contract="Demo.ITestContract1" bindingConfiguration="NetTcpBindingConfiguration"/>
     <endpoint address="mex" binding="netTcpBinding" contract="IMetadataExchange" bindingConfiguration="MexBindingConfiguration"/>
    </service>
    <service name="Demo.TestService2" behaviorConfiguration="NetTcpServiceBehavior">
      <host>
        <baseAddresses>
          <add baseAddress="net.tcp://localhost:9999/TestService2"/>
        </baseAddresses>
      </host>
      <endpoint address="" binding="netTcpBinding" contract="Demo.ITestContract2" bindingConfiguration="NetTcpBindingConfiguration"/>
      <endpoint address="mex" binding="netTcpBinding" contract="IMetadataExchange" bindingConfiguration="MexBindingConfiguration"/>
    </service>
  </services>
  <bindings>
    <netTcpBinding>
      <binding name="NetTcpBindingConfiguration"
               maxConnections="5"
               portSharingEnabled="true">
        <security mode="None">
          <transport protectionLevel="None"/>      
        </security>
      </binding>
      <binding name="MexBindingConfiguration" portSharingEnabled="true">
        <security mode="None">
          <transport protectionLevel="None"/>    
        </security>
      </binding>
    </netTcpBinding>
  </bindings>
  <behaviors>
    <serviceBehaviors>
      <behavior name="NetTcpServiceBehavior">
        <serviceMetadata />
      </behavior>
    </serviceBehaviors>
  </behaviors>
</system.serviceModel>