我必须传达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();
}
}
答案 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类中 - 它只需要回调接口即可调用它。实际上你可能不需要这个 - 我不知道在什么情况下你想回电话给客户