Creating a WCF Duplex Service on Azure with a Silverlight Client

I had some trouble to build correctly a simple WCF Duplex Service that run on Windows AZURE while the Connection is made anonymously, after a lot of research I decided to share my solution
so basicaly the solution is quite simple,

the only thing you have to remember is:

  1. your client is a Silverlight one so you have some limitation about you'r Binding Protocol
  2. your Server is on an Azure PLatform so lets try to use what Azure can Offer to us
  3. we need a Duplex Service so not all the Bindings can fit
  4. We wan to do that without using any authentication to forget about WSHttpBinding or simillar Protocols

 


 

In order to do that i decided to use a Custom Binding made by Microsoft. You will be able to find this custom Binding in the Microsoft SDK Folder( Program Files => Microsoft SDKs)  in the Silverlight Folder, Choose your Version(i'm using 4.0),under Library Folder you will find the System.ServiceModel.PollingDuplex.dll for your Client and your Service. after i added those DLLs to my Solution, i have to setup my config file:

Server

For the Server i have a simple WCFWorker Role:
in the Config file of our service we have to add the dll to the config file:

 

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


Binding:

 

<bindings>
      <pollingDuplexHttpBinding>
        <binding name="PubSub" duplexMode="MultipleMessagesPerPoll" /></pollingDuplexHttpBinding>    
</bindings>

 

Behavior:

 

<behaviors>
      <serviceBehaviors>
        <behavior name="PubSubServiceBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
          <serviceThrottling maxConcurrentSessions="2147483647" />
        </behavior>
      </serviceBehaviors>
    </behaviors>

 

Service:


  <system.serviceModel>
    <extensions>
      <bindingExtensions>
        <add name="pollingDuplexHttpBinding" type="System.ServiceModel.Configuration.PollingDuplexHttpBindingCollectionElement, System.ServiceModel.PollingDuplex, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
      </bindingExtensions>
    </extensions>
    <bindings>
      <pollingDuplexHttpBinding>
        <binding name="PubSub" duplexMode="MultipleMessagesPerPoll" />
      </pollingDuplexHttpBinding>
    </bindings>
    <!-- Ensure this setting is present for WCF to pick up base addresses correctly in Azure. -->
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
    <behaviors>
      <serviceBehaviors>
        <behavior name="PubSubServiceBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
          <serviceThrottling maxConcurrentSessions="2147483647" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration="PubSubServiceBehavior" name="WCFServiceWebRole2.Service1">
        <endpoint address="" binding="pollingDuplexHttpBinding" bindingConfiguration="PubSub" contract="WCFServiceWebRole2.IService1" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
  </system.serviceModel>

 

In our Code we don't need anything Special, just our regular configuration,

for example:

 

[ServiceContract(CallbackContract = typeof(IServiceCallBack))]
    public interface IService1
    {
        [OperationContract(IsOneWay = true)]
        void GetData(int value);
    }

    [ServiceContract]
    public interface IServiceCallBack
    {
        [OperationContract(IsOneWay = true)]
        void MessageReceived(string message);
    }

 

and just For the Example i have a simple Implementation:

 

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)]
    public class Service1 : IService1
    {
        public void GetData(int value)
        {
            callbackmanager CM = new callbackmanager(Callback, value + " - " + OperationContext.Current.SessionId);
            Task.Factory.StartNew(CM.SendMssg);
        }
        IServiceCallBack Callback
        {
            get
            {
                return OperationContext.Current.GetCallbackChannel<IServiceCallBack>();
            }
        }
    }
    public class callbackmanager
    {
        IServiceCallBack _callback;
        string UserMessage;
        public callbackmanager(IServiceCallBack callback, string usermsg)
        {
            _callback = callback;
            UserMessage = usermsg;
        }
        public void SendMssg()
        {
            Thread.Sleep(5000);
            _callback.MessageReceived(UserMessage);
        }
    }



Client:

For our Client we have to remember to add our Dll also situated at :C:\Program Files\Microsoft SDKs\Silverlight\v4.0\Libraries\Client\System.ServiceModel.PollingDuplex.dll

now just Search for the Service you just published, you will see the Service reference add automaticaly and that's it you'r good to go :)
In case that in the ServiceReference client config there is nothing about this new service,
you can add by yourself the configuration like that:

<system.serviceModel>
    <bindings>
      <customBinding>
        <binding name="CustomBinding_IPubSub">
          <pollingDuplex duplexMode="MultipleMessagesPerPoll" />
          <binaryMessageEncoding />
          <httpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647"
                         transferMode="StreamedResponse"/>
        </binding>
      </customBinding>
    </bindings>
    <client>
      <endpoint address="http://127.0.0.1:8080/InsightService.svc"
       binding="customBinding" bindingConfiguration="CustomBinding_IPubSub"
       contract="ServiceReference2.IDataService" name="CustomBinding_IPubSub" />
    </client>
    <extensions />
  </system.serviceModel>



but if you have to update your service reference you will have to delete this configuration from your file and add it again manuallyhope that helped you :0)

Jeremy Souffir

Last edited Apr 5, 2012 at 8:30 AM by jerems6, version 13