Search code examples
wcfsilverlight-5.0pollingduplexhttpbinding

PollingDuplexHttpBinding and DuplexChannelFactory - 'ContractFilter mismatch at the EndpointDispatcher'


I'm writing a duplex service which is to be consumed by a Silverlight 5 client. My server config looks like this (in the right places obviously)-

            <bindingExtensions>
                <add name="pollingDuplexHttpBinding"
                     type="System.ServiceModel.Configuration.PollingDuplexHttpBindingCollectionElement, System.ServiceModel.PollingDuplex, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
            </bindingExtensions>

<pollingDuplexHttpBinding>
                <binding name="multipleMessagesPerPollPollingDuplexHttpBinding"
                         duplexMode="MultipleMessagesPerPoll"
                         maxOutputDelay="00:00:07"/>
            </pollingDuplexHttpBinding>

<endpoint address="Duplex"
                          binding="pollingDuplexHttpBinding"
                          bindingConfiguration="multipleMessagesPerPollPollingDuplexHttpBinding"
                          contract="ProActive.Domain.Interfaces.IDuplexService"/>

The contract you see there is this -

[ServiceContract(Name = "IDuplexService", CallbackContract = typeof(IDuplexClient))]
    public interface IDuplexServiceAsync
    {
        [OperationContract(AsyncPattern = true)]
        IAsyncResult BeginConnect(int userId, AsyncCallback callback, object asyncState);

        void EndConnect(IAsyncResult result);
    }

[ServiceContract]
public interface IDuplexClient
{
    [OperationContract(IsOneWay = true)]
    void Refresh();
}

This seems to host just fine but I'm not 100% sure of that.

My client code looks like this -

public class client : IDuplexClient
{
    #region IDuplexClient Members

    public void Refresh()
    {

    }

    #endregion
}



 public someOtherClass
    {
var binding = new PollingDuplexHttpBinding();
            binding.DuplexMode = PollingDuplexMode.MultipleMessagesPerPoll;

            var address = new EndpointAddress("http://" + ConfigService.ServerName + "/Service.svc/Duplex/");

            var factory = new DuplexChannelFactory<IDuplexServiceAsync>(
                new InstanceContext(new client()), binding).CreateChannel(address);
            factory.BeginConnect(0, new AsyncCallback((result) =>
                {
                    factory.EndConnect(result);

                }), null);

    }

I'm getting a ContractFilter mismatch problem when I step over 'factory.EndConnect(result)' but I don't see why. Obviously on the server I'm implementing the synchronous version of the Async interface (So just Connect and not Begin/EndConnect) but that's the only place I can think of there being a mismatched contract here.

I'm really pulling my hair out now...and I'm already bald! Any help would be really appreciated.

Thanks in advance.


Solution

  • Please try it by explictly setting the name and namespaces of your service interfaces, you shouldn't have a problem in a mismatch due to different CLR namespaces in the client and server.

    [ServiceContract(Name = "IClient", Namespace = "http://your.namespace")]
    public interface IClient
    {
        [OperationContract(IsOneWay = true)]
        void DoSomething();
    
        [OperationContract(IsOneWay = true)]
        void DoSomethingElse();
    }
    
    [ServiceContract(Name = "IServer", Namespace = "http://your.namespace", CallbackContract = typeof(IClient))]
    public interface IServer
    {
    #if !SILVERLIGHT
        [OperationContract]
        string Operation1(string userName);
    
        [OperationContract]
        int Operation2(int x, int y);
    #else
        [OperationContract(AsyncPattern = true)]
        IAsyncResult BeginOperation1(string userName, AsyncCallback callback, object state);
        string EndOperation1(IAsyncResult asyncResult);
    
        [OperationContract(AsyncPattern = true)]
        IAsyncResult BeginOperation2(int x, int y, AsyncCallback callback, object state);
        int EndOperation2(IAsyncResult asyncResult);
    #endif
    }