WPF上的多WCF回调接口

时间:2011-11-24 10:28:46

标签: wcf

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

当其中一个调用服务上的方法时,服务会回调给另一个方法。只有一个回调接口,所有方法都写在其中。但是,2个WPF应用程序没有使用相同的回调方法。所以,我被迫实施未使用的方法。

所以,我试图找到我是否可以在服务上设置2个不同且独立的回调接口,但我不能。有没有办法做到这一点?

更新

我的示例代码:

IDeviceCallBack

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

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

public interface IDeviceCallback : ITestCallBack1, ITestCallBack2
{ }

i设备

[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

[CallbackBehaviorAttribute(ConcurrencyMode = ConcurrencyMode.Multiple)]
public partial class MainWindow : Window, ITestCallBack1, IDisposable//,IDeviceCallBack
{
    private InstanceContext context;
    private DeviceClient deviceClient;

    public MainWindow()
    {
        InitializeComponent();
        context = new InstanceContext(this);
        deviceClient = new DeviceServiceReference.DeviceClient(context);
    }

    public void Dispose()
    {
        deviceClient.Close();
    }

    public void Test1()
    {
        throw new NotImplementedException();
    }

    // Not Wanted
    //public void Test2()
    //{
    //    throw new NotImplementedException();
    //}
}

WPF2

[CallbackBehaviorAttribute(ConcurrencyMode = ConcurrencyMode.Multiple)]
public partial class MainWindow : Window, ITestCallBack2, IDisposable //,IDeviceCallBack
{
    private InstanceContext context;
    private DeviceClient deviceClient;

    public MainWindow()
    {
        InitializeComponent();
        context = new InstanceContext(this);
        deviceClient = new DeviceServiceReference.DeviceClient(context);
    }

    public void Dispose()
    {
        deviceClient.Close();
    }

    // Not Wanted
    //public void Test1()
    //{
    //    throw new NotImplementedException();
    //}

    public void Test2()
    {
        throw new NotImplementedException();
    }
}

1 个答案:

答案 0 :(得分:2)

我对你的要求并不完全清楚,但无论如何我都会帮忙......

因此,在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();
    }
}   

以下是服务的配置:

<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>

然后在客户端上,您需要引用您对回调感兴趣的服务(因此您的WPF 1将引用/ TestService1和WPF 2 / TestService2)。

请注意,您可以将两个服务共有的所有逻辑放在TestServiceBase类中 - 它只需要回调接口即可调用它。实际上你可能不需要这个 - 我不知道在什么情况下你想回电话给客户