我是wcf的新手,并学习如何使用回调来构建一个。我从以下链接得到了一个例子:
http://architects.dzone.com/articles/logging-messages-windows-0
我尝试实现wcf但是当我通过按f5将其作为测试运行时,测试客户端说:
wcf客户端不支持服务合同。
服务
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant, InstanceContextMode = InstanceContextMode.PerCall)]
public class RatsService : IRatsService
{
public static List<IRatsServiceCallback> callBackList = new List<IRatsServiceCallback>();
public RatsService()
{
}
public void Login()
{
IRatsServiceCallback callback = OperationContext.Current.GetCallbackChannel<IRatsServiceCallback>();
if (!callBackList.Contains(callback))
{
callBackList.Add(callback);
}
}
public void Logout()
{
IRatsServiceCallback callback = OperationContext.Current.GetCallbackChannel<IRatsServiceCallback>();
if (callBackList.Contains(callback))
{
callBackList.Remove(callback);
}
callback.NotifyClient("You are Logged out");
}
public void LogMessages(string Message)
{
foreach (IRatsServiceCallback callback in callBackList)
callback.NotifyClient(Message);
}
服务界面
[ServiceContract(Name = "IRatsService", SessionMode = SessionMode.Allowed, CallbackContract = typeof(IRatsServiceCallback))]
public interface IRatsService
{
[OperationContract]
void Login();
[OperationContract]
void Logout();
[OperationContract]
void LogMessages(string message);
// TODO: Add your service operations here
}
public interface IRatsServiceCallback
{
[OperationContract]
void NotifyClient(String Message);
}
App.config中:
<system.serviceModel>
<services>
<service name="RatsWcf.RatsService">
<endpoint address="" binding="wsDualHttpBinding" contract="RatsWcf.IRatsService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8733/Design_Time_Addresses/RatsWcf/Service1/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information,
set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
<!-- To receive exception details in faults for debugging purposes,
set the value below to true. Set to false before deployment
to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
只是想知道这里可能出现什么问题。
答案 0 :(得分:3)
没有错。 WCF测试客户端是一个可用于测试多种类型的WCF服务的工具,但不是所有这些服务 - 双工合同是一个不受支持的类别。您需要创建某种客户端应用程序来测试它。在您的客户端应用程序中,您需要编写一个实现回调接口的类,以便它可以接收服务启动的消息。
例如,这是一个使用WCF双工的非常简单的双工客户端/服务:
public class DuplexTemplate
{
[ServiceContract(CallbackContract = typeof(ICallback))]
public interface ITest
{
[OperationContract]
string Hello(string text);
}
[ServiceContract(Name = "IReallyWantCallback")]
public interface ICallback
{
[OperationContract(IsOneWay = true)]
void OnHello(string text);
}
public class Service : ITest
{
public string Hello(string text)
{
ICallback callback = OperationContext.Current.GetCallbackChannel<ICallback>();
ThreadPool.QueueUserWorkItem(delegate
{
callback.OnHello(text);
});
return text;
}
}
class MyCallback : ICallback
{
AutoResetEvent evt;
public MyCallback(AutoResetEvent evt)
{
this.evt = evt;
}
public void OnHello(string text)
{
Console.WriteLine("[callback] OnHello({0})", text);
evt.Set();
}
}
public static void Test()
{
string baseAddress = "net.tcp://" + Environment.MachineName + ":8000/Service";
ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
host.AddServiceEndpoint(typeof(ITest), new NetTcpBinding(SecurityMode.None), "");
host.Open();
Console.WriteLine("Host opened");
AutoResetEvent evt = new AutoResetEvent(false);
MyCallback callback = new MyCallback(evt);
DuplexChannelFactory<ITest> factory = new DuplexChannelFactory<ITest>(
new InstanceContext(callback),
new NetTcpBinding(SecurityMode.None),
new EndpointAddress(baseAddress));
ITest proxy = factory.CreateChannel();
Console.WriteLine(proxy.Hello("foo bar"));
evt.WaitOne();
((IClientChannel)proxy).Close();
factory.Close();
Console.Write("Press ENTER to close the host");
Console.ReadLine();
host.Close();
}
}