user726720
user726720

Reputation: 1237

WCF service contract not supported in test client

I'm new to wcf and learning how to build one, with callbacks. I got an example from the following link:

http://architects.dzone.com/articles/logging-messages-windows-0

I tried implementing the wcf but when i run this in as a test by pressing f5, the test client says:

The service contract is not supported in the wcf client.

Service:

[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);

    }

Service Interface

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

Just wondering what could be wrong here.

Upvotes: 2

Views: 2015

Answers (1)

carlosfigueira
carlosfigueira

Reputation: 87228

There's nothing wrong. The WCF Test Client is a tool which can be used to test many types of WCF services, but not all of them - duplex contracts being one category which is not supported. You'll need to create some sort of client app to test that. In your client app you'll need to write a class which implements the callback interface, so that it can receive the messages initiated by the service.

For example, this is a very simple duplex client / service which uses WCF duplex:

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();
    }
}

Upvotes: 4

Related Questions