Monday, 5 January 2015

Push model(Callback, WSDualHttpBinding) overview

About 

WCF service example to explain how and when to implement callback model (WSDualHttpBinding)

Prerequisite 

Reader of this article should have basic understanding of WCF, End points, Visual studio and bindings.

Background 

In our day to day operations we come across scenarios where we have to reflect changes on client when there is some change done sever. One way is to implement polling model where client will keep on polling server to check changes but this approach is very inefficient better way is to implement a mechanism where server can push client to reflect update whenever corresponding change occurs on server. WCF provide WSDualHttpBinding or (Duplex) to achieve same very efficiently. Below I have described set by step example to explain implementation.

Introduction 

In the example described below a client application is sending a request to server for registration of name. On registration, server is sending a notification to client for successful registration. To make the notification more responsive I have used timer to send notification in intervals.
This example has three components
  1. Service library - Server with DuplexServiceLibrary (WCF service library) which have implementation of service & service contracts.
  2. Service host – A console application to host the service.
  3. Client – A console application to act as client (consumer of service)

Implementing server

In visual studio add new project, add WCF Service library. Here VS 2012 is used but VS 2008 can also be used 
Below is the service contract IDuplexService containing the method for registration. To keep simple only one method is added in it. We need to add CallbackContract attribute to define callback service interface for 
 [ServiceContract(SessionMode = SessionMode.Required,
                 CallbackContract = typeof(IDuplexServiceCallback))]
  public interface IDuplexService {

    [OperationContract(IsOneWay = true)]
    void Registration(string Name);
   
  }

Below is the callback Interface definition which consists of NotifyRegistration method which will result in sending notification to clients. OperationContract message exchange pattern is one way (IsOneWay = true) because in this case only one message is transmitted. The receiver does not send a reply message, nor does the sender expect one.
[ServiceContract]
  public interface IDuplexServiceCallback {

    [OperationContract(IsOneWay = true)]
    void NotifyRegistration(string Name);        
  }
Implement the DuplexService for Registration. Here timer is used to invoke callback method at regular interval which can be update client respectively.
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
    public class DuplexService : IDuplexService
    {

        #region IDuplexService Members

        string result = "Your request has been regitered by Application ";
        public static Timer Timer;
        public static IDuplexServiceCallback Callback;

        public DuplexService()
        {            
        }

        public void Registration(string Name)
        {
            Callback = OperationContext.Current.GetCallbackChannel<IDuplexServiceCallback>();
            result = Name + " :: " + result;
            Timer = new Timer(1000);
            Timer.Elapsed += OnTimerElapsed;
            Timer.Enabled = true;
        }

        void OnTimerElapsed(object sender, ElapsedEventArgs e)
        {
            string notification = result + " @ " + DateTime.Now.ToString();
            Callback.NotifyRegistration(notification);
        }
Now we need to define end point on server. For call back service (push model) we need wsDualHttpBinding. Below is the complete app.config code for service.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>

  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" />
  </system.web>
  <!-- When deploying the service library project, the content of the config file must be added to the host's 
  app.config file. System.Configuration does not support config files for libraries. -->
  <system.serviceModel>
    <services>
      <service name="DuplexServiceLibrary.DuplexService">
        <host>
          <baseAddresses>
            <add baseAddress = "http://localhost:8090/DuplexService/" />
          </baseAddresses>
        </host>
        <!-- Service Endpoints -->
        <!-- Unless fully qualified, address is relative to base address supplied above -->
        <endpoint address="" binding="wsDualHttpBinding" contract="DuplexServiceLibrary.IDuplexService">
          <!-- 
              Upon deployment, the following identity element should be removed or replaced to reflect the 
              identity under which the deployed service runs.  If removed, WCF will infer an appropriate identity 
              automatically.
          -->
          <identity>
            <dns value="localhost"/>
          </identity>
        </endpoint>
        <!-- Metadata Endpoints -->
        <!-- The Metadata Exchange endpoint is used by the service to describe itself to clients. --> 
        <!-- This endpoint does not use a secure binding and should be secured or removed before deployment -->
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </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>
  </system.serviceModel>

</configuration>

Implementing service host

Now with service ready we now have to implement service host. We can use new command line application to create a host name DuplexServiceHost. Add reference of DuplexServiceLibrary and initialize the service host 
 
 static void Main(string[] args) {

      ServiceHost host = new ServiceHost(typeof(DuplexService));

      ConsoleColor oldColour = Console.ForegroundColor;
      Console.ForegroundColor = ConsoleColor.Yellow;

      Console.WriteLine("DuplexService is up and running with the following endpoints:");
      foreach (ServiceEndpoint se in host.Description.Endpoints)
        Console.WriteLine(se.Address.ToString());
      Console.ReadLine();

      host.Open();

      host.Close();
    }
Now add new App.config file to this console application and copy the app.config of the DuplexService.

Implementing Client.

Add new console application (name DuplexClient ) to the solution and rename class program to client (just to have different name from service host). Now add service reference to client with  namespace DuplexServiceReference
 
Adding service reference will add new app.config to the client with required endpoints.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <bindings>
      <wsDualHttpBinding>
        <binding name="WSDualHttpBinding_IDuplexService" clientBaseAddress="http://localhost:8091/" />
      </wsDualHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://localhost:8090/DuplexService/" binding="wsDualHttpBinding"
        bindingConfiguration="WSDualHttpBinding_IDuplexService" contract="DuplexServiceReference.IDuplexService"
        name="WSDualHttpBinding_IDuplexService">
        <identity>
          <dns value="localhost" />
        </identity>
      </endpoint>
    </client>
  </system.serviceModel>
</configuration>
Now implement Client. Define duplexClient for the service as below.
private static DuplexServiceReference.DuplexServiceClient duplexClient;
Define new class to implement the NotifyRegistration method of the IDuplexServiceCallback contract as shown below
public class DuplexServiceCallBackHandler : DuplexServiceReference.IDuplexServiceCallback{

        public void NotifyRegistration(string Name){
            ConsoleColor oldColour = Console.ForegroundColor;
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine("Notification : ({0})", Name);
        }

    }
Instantiate the context for the service in Main method.
InstanceContext context = new InstanceContext(new DuplexServiceCallBackHandler());
            duplexClient = new DuplexServiceReference.DuplexServiceClient(context, "WSDualHttpBinding_IDuplexService");
Call the registration method of the service
duplexClient.Registration(name);
Console.ReadLine();
Complete implementation of Client is given below.
   class Client{
        private static DuplexServiceReference.DuplexServiceClient duplexClient;
        static void Main(string[] args){

            InstanceContext context = new InstanceContext(new DuplexServiceCallBackHandler());
            duplexClient = new DuplexServiceReference.DuplexServiceClient(context, "WSDualHttpBinding_IDuplexService");
            try{

                Console.WriteLine("This is a client, press enter initiate request to server");
                Console.ReadLine();
                string name = "Sudhir";
                duplexClient.Registration(name);
                Console.ReadLine();
            }

            catch (TimeoutException timeProblem){
                Console.WriteLine("The service operation timed out. " + timeProblem.Message);
                duplexClient.Abort();
                Console.Read();
            }
            catch (CommunicationException commProblem){
                Console.WriteLine("There was a communication problem. " + commProblem.Message);
                duplexClient.Abort();
                Console.Read();
            }
        }
    }

    public class DuplexServiceCallBackHandler : DuplexServiceReference.IDuplexServiceCallback
    {
        public void NotifyRegistration(string Name){
            ConsoleColor oldColour = Console.ForegroundColor;
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine("Notification : ({0})", Name);
        }
    }
Now with client and server ready go to solution properties and set multiple startup projects
Now build solution and run. It will show two command prompts. One for service host which shows the service endpoint defined. Other one is client. As per logic written in client press enter to register on server with defined interval on server client will be updated with the notification. Please ensure to run Visual studio in Admin mode.
Complete solution can be downloaded to see the implementation. 

Thursday, 23 October 2014

IIS performance improvement

Introduction

These days in web application performance is very crucial from user and business point of you.  Everyone wants better performance and response from web application. In this article I am going to highlight ways to improve performance from Internet information server serving faster web pages to your users.


Disable IIS logging.
In IIS we can log the details of a HTTP request like client ip, time taken, response size, cookie etc into a file.  This information helps to find the load on the server in terms of number of requests, size and time taken to serve the request which consume IIS resource, so this feature can either be disabled or we can set a number of essential events to log in server
To disable IIS logging open IIS giving “inetmgr” command in run window. Double click on logging Icon.




Click on the disable option on the right pane. Remember that you can set logging option both in server level and website level. 





ASP debugging

In production environment ASP debugging mode is required to help you quickly locate bugs and interactively test your server-side scripts. Stopping debugging mode will save you a great amount of processing power.
To disable debugging:  open IIS giving “inetmgr” command in run window. Select the web site, double-click the ASP feature.



Select Compilation > click to expand Debugging Properties > Both Enable Client-side Debugging and Enable Server-side Debugging false should be set to fare set to False.




ASP Threads Per Processor
This value define limit of maximum no of ASP request can be executed simultaneously. It should be set to the no of threads that will consume 50% of processor time. To handle more request its value should be increased The default value of Threads Per Processor Limit is 25. The maximum recommended value for this property is 100. Set this property as per your concurrent requests.

To set this property open ASP feature as described above. Click to expand Limits Properties under Behavior > click Threads Per Processor Limit > enter the desired value for Threads Per Processor Limit



ASP Queue Length property
This property is to ensure good response time while minimizing how often the server sends the HTTP 503 (Server Too Busy) error to clients when the ASP request queue is full. If the value of ASP Queue Length property is too low, the server will send the HTTP 503 error with greater frequency. If the value of ASP Queue Length property is too high, users might perceive that the server is not responding when in fact their request is waiting in the queue.
Set the value of the ASP Queue Length property just above the peak value.If you do not have data for adjusting the ASP Queue Length property, Set a one-to-one ratio of queues to total threads. For example, if the ASP Threads Per Processor Limit property is set to 25 and you have four processors (4 * 25 = 100 threads), set the ASP Queue Length property to 100 and tune from there.



Enable IIS HTTP compression
By enabling the IIS compression we can utilize the band width in more efficient way.It enables faster data transmission between compression enabled browser and client regardless of whether your content is served from local storage or a UNC resource.

To enable HTTP compression
1. Open IIS
2. Click on compression features to open it, for particular website
3. Enable dynamic and static compression
see below snap for more detail






Enable output caching
Caching is the feature which helps to improve the speed of the IIS by taking copy of a webpage visited by most recent user. If a new user requests the very same webpage located in the cache, IIS will send the copy from its cache without reprocessing the contents. Output caching can significantly improve your server response time for dynamic contents
Refer link Output Caching to see how to configure it.

Composition, Aggregation and Inheritance

Introduction 


In UML people generally get confused between terms Composition and Aggregation and some time with Inheritance. Below these three relations are explained with UML diagram to example the difference.

Composition:

When one (A) class have reference of instance of another class (B) and all the access that instance is controlled by container class (A), then this relation is called composition. A is a composition of B. For example one company (class A) can have many departments. So Company is composition of department (Class B). Department do not have its identity without company, here departments are owned by company so this type of relation is also called "owns a" relation. Below is the UML representation.

Aggregation:

When a class A contains a reference of class B which also have instance and accessible outside A, then this relationship is called aggregation and B is aggregation of A. For example department in above example can have employees but same employ can work for other department also witness same role. So different departmental have instance of employee (B) and employee can exist independent of the department(A). We can say A class has a object of class B. This kind of relation are also called "has a" relation. Below is the UML representation.

Inheritance:

When a class A contains all the members of class B, it is call A extends B or A inherits B. In above example employee class inherits a person class. Such kind of relations are also called "is a" relation. Below is the UML representation.

Complete class diagram