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