Showing posts with label WCF. Show all posts
Showing posts with label WCF. Show all posts

Thursday, December 26, 2013

Create a WCF Rest service with response type xml and json

In article we are going to see how to create a WCF rest service with response type as xml and json. To create REST service three things need to be kept in mind.

1. Endpoint Binding should be webHttpBinding
2. Create  EndPoint behaviour and add <webHttp />
3. Create a UriTemplate and specify the WebGet or WebInvoke attribute

UriTemplate : Specify what kind of uri need to specify to that method
ResponseFormat : Specify the Response Format Xml or Json
Method :   POST or GET

web.config

    <behaviors>
      <serviceBehaviors>
        <behavior name="Restsample.Service1Behavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="Rest">
          <webHttp />
        </behavior>
      </endpointBehaviors>
    </behaviors>


<endpoint address="" behaviorConfiguration="Rest" binding="webHttpBinding" contract="Restsample.IService1">  

C# code

  public interface IService1
    {
        [OperationContract]
        [WebGet(UriTemplate="/",ResponseFormat=WebMessageFormat.Json)]
        int Add();

        [OperationContract]
        [WebGet(UriTemplate="/GetEmp",ResponseFormat=WebMessageFormat.Xml)]
        List<Employee> GetEmployees();

        [OperationContract]
        [WebInvoke(UriTemplate="/Add?a={a}",Method="GET",ResponseFormat=WebMessageFormat.Json)]
        int AddOperation(inta);

        [OperationContract]
        [WebInvoke(UriTemplate = "/Sub?a={a}&b={b}", Method = "POST", ResponseFormat = WebMessageFormat.Json)]
        int SubOperation(inta,int b);

    }
}

public class Service1 : IService1
    {
            
        public int Add()
        {
            return 10;
        }


        public List<Employee> GetEmployees()
        {
            List<Employee> employees = new List<Employee>();
            employees.Add(new Employee() { EmpID = 1,EmpName="Rajesh",Address="Chennai"});
            employees.Add(new Employee() { EmpID = 2, EmpName = "Suresh", Address = "Mumbai" });
            employees.Add(new Employee() { EmpID = 3, EmpName = "Ramesh", Address = "Bangalore" });
            employees.Add(newEmployee() { EmpID = 4, EmpName = "Siva", Address = "Delhi" });
            employees.Add(new Employee() { EmpID = 5, EmpName = "Farath", Address = "Hyderabad" });
            return employees;
        }


        public intAddOperation(int a)
        {
            return 1 + a;
        }


        public intSubOperation(int a, intb)
        {
            return a + b;
        }
    }


    [DataContract]
    public class Employee
    {
        [DataMember(Order=1)]
        public int EmpID { set; get; }

        [DataMember(Order=2)]
        public string EmpName { set; get; }

        [DataMember(Order=3)]
        public string Address { set; get; }
    }


Invoke service from browser :

Call a AddOperation method in browser 

output : 2


Following uri will call the Add method
http://localhost/Restsample/service1.svc/

output: 10

Following Uri will call the add employee method
http://localhost/Restsample/service1.svc/GetEmp

output:

Json

[
    {"EmpID":1,"EmpName":"Rajesh","Address":"Chennai"},
    {"EmpID":2,"EmpName":"Suresh","Address":"Mumbai"},
    {"EmpID":3,"EmpName":"Ramesh","Address":"Bangalore"},
    {"EmpID":4,"EmpName":"Siva","Address":"Delhi"},
    {"EmpID":5,"EmpName":"Farath","Address":"Hyderabad"}
]

Xml

<ArrayOfEmployee xmlns="http://schemas.datacontract.org/2004/07/Restsample" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <Employee>
        <EmpID>1</EmpID>
        <EmpName>Rajesh</EmpName>
        <Address>Chennai</Address>
    </Employee>
    <Employee>
        <EmpID>2</EmpID>
        <EmpName>Suresh</EmpName>
        <Address>Mumbai</Address>
    </Employee>
    <Employee>
        <EmpID>3</EmpID>
        <EmpName>Ramesh</EmpName>
        <Address>Bangalore</Address>
    </Employee>
    <Employee>
        <EmpID>4</EmpID>
        <EmpName>Siva</EmpName>
        <Address>Delhi</Address>
    </Employee>
    <Employee>
        <EmpID>5</EmpID>
        <EmpName>Farath</EmpName>
        <Address>Hyderabad</Address>
    </Employee>
</ArrayOfEmployee>



From this article we can understand how to create a REST WCF service.

Sunday, October 20, 2013

WCF - Create a Publisher and Subscriber model by various Cricket notification from Service to client.




What is Publisher and Subscriber model ?
   Publisher is a term which will publish the content to the client that who are subscribed, Subscriber's are the client who can subscribe the notifications.They are two ways you can get the changed data from server by Pulling and Pushing. 

Pulling Method :
                Pulling is the method , where client will get the data from server after a consecutive interval . For example in a website state the status of cricket match, What they do is Pulling method after a 10 sec browser hit the server and get the latest changes from the server. This method will not suit for all notification because if we are going to notify a Football match what will happen goal will put by each team after a half an hour sometimes more than one hour. For this scenario consider each and every 10 seconds if browser hit the server resources cost increases and makes server slow to perform. how to avoid this we can make a Pushing method

Pushing Method : 
              Pushing Method, In this method server will push the change data to the all clients which are connected  and subscribed the notifications.

To Implement the Publisher and Subscriber model we are going to use a WCF with an example of Cricket Match.

Example : Consider a Cricket match going to held we need a notification from the Server with following conditions

1.   Wicket
2.   Five Over Once 
3.   Fifty Runs Once

The beauty of this example we are going to create a single instance for same Client Request even though he request for many times we uses the same single instance that are created before.[singleton service]

1. At the which stage uses click notification , it starts notify the user to notify the update to client.
2. Three options we have on which type we have to notify on every wicket it will notify if the subscriber subscribe the activate.
3. If we close the client and again open the client give the request of notification it will notifies the latest update.
4. wsDualHttpBinding which makes the dual communication from server to client for binding.

Client open and click the following three buttons and get the notifies.





Close the Client and again the launch it and click the notifies button , you can see the latest update is notifies.


See the second screen that from the 8th wicket it s get notified.

Service Code :

Contract :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace CricInfoService
{
    public enum NotifyMode
    {
        Wicket,
        Over,
        FiveOverOnce,
        Runs,
        FiftyRunsOnce
    }

    [ServiceContract(CallbackContract=typeof(IClientCallback))]
    interface ICricketService
    {
        [OperationContract]
        bool GetNotification(NotifyModemode,string username);

        [OperationContract(IsOneWay=true)]
        void GetNotify(NotifyModemode, string username);
    }

    public interface IClientCallback
    {      
        [OperationContract(IsOneWay=true)]
        void AsyncNotifyMessage(stringmessage);
    }

}


 Service : InstanceContextMode is single which specifies the singleton

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace CricInfoService
{
    [ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
    public class CricketService:ICricketService
    {
        private static int _wicket = 0;
        private static int _run = 0;
        private static double _over = 0;
        static Random rand = new Random();

        static int Wicket
        {
            set {
                if (!value.Equals(_wicket))
                {
                    _wicket = value;
                    SendNotifyToClient(NotifyMode.Wicket);
                }
            }
            get { return _wicket; }
        }

        static int Run
        {
            set {

                if (!value.Equals(_run))
                {
                    _run = value;
                    if (_run % 50 == 0 )
                    {
                        SendNotifyToClient(NotifyMode.FiftyRunsOnce);
                    }
                 
                }           
            }
            get { return _run; }
        }

        static double Over
        {
            set
            {
                if (!value.Equals(_over))
                {
                    _over = value;

                    int whole =Convert.ToInt32(Math.Truncate(_over));
                       
                    if(_over - whole >= 0.6)
                    {
                        _over = Math.Ceiling(_over);
                    }
                                                
                    if (_over % 5 == 0)
                    {
                        SendNotifyToClient(NotifyMode.FiveOverOnce);
                    }
                }
            }
            get { return _over; }
        }

        public class CricketData
        {
            public  OperationContext CricketContext{set;get;}

            public NotifyModeMode {set;get;}

            public stringUserName {set;get;}           

        }

        static List<CricketData> notifylist = null;

        public CricketService()
        {
            notifylist = new List<CricketData>();
            System.Threading.Thread th = new System.Threading.Thread(Publisher);
            th.Start();
        }

        public boolGetNotification(NotifyMode mode, string username)
        {
            try
            {
                if (mode == NotifyMode.Wicket || mode == NotifyMode.FiveOverOnce || mode == NotifyMode.FiftyRunsOnce)
                {
                    notifylist.Add(new CricketData()
                    {
                        CricketContext= OperationContext.Current,
                        Mode=mode,
                        UserName=username
                    });
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exceptionex)
            {
                throw newFaultException(ex.Message);
            }
        }

        public voidGetNotify(NotifyMode mode, string username)
        {
            try
            {
                if (mode == NotifyMode.Wicket || mode == NotifyMode.FiveOverOnce || mode ==                                NotifyMode.FiftyRunsOnce)
                {
                    notifylist.Add(new CricketData()
                    {
                        CricketContext = OperationContext.Current,
                        Mode = mode,
                        UserName = username
                    });                   
                }            
            }
            catch (Exceptionex)
            {
                throw newFaultException(ex.Message);
            }
        }

        void Publisher()
        {
            DateTime start = DateTime.Now;
            DateTime Modified =DateTime.Now;

           DateTime wt = DateTime.Now.AddMinutes(NotifySecond(NotifyMode.Wicket));           

            while (true)
            {
                int now = DateTime.Now.Minute;

                if(Wicket<=10)
                    if (wt.Minute == now)
                    {
                        Wicket++;                       
                        wt = wt.AddMinutes(NotifySecond(NotifyMode.Wicket));
                    }
                    else
                    {
                        if((DateTime.Now - Modified).Seconds > 6)
                        {
                            Over += 0.1;
                            Run += 1;
                            Modified = DateTime.Now;
                        }                      
                    }              

                if (Wicket > 10)                                   
                    break;
            }
        }

        private static void SendNotifyToClient(NotifyModemode)
        {
            for (int i = 0; i < notifylist.Count; i++)
            {
                CricketData data = notifylist[i];                            
                if (data.Mode == mode)
                {
                    Send(data);
                }               
            }                           
        }

        private static void Send(CricketDatadata)
        {
            int f = NotifySecond(data.Mode);           
            IClientCallbackclient = 
                       data.CricketContext.GetCallbackChannel<IClientCallback>();
            String message = string.Format("{1}/{0} : Runs/Wickets {2} Overs", Wicket, 
                       Run, Over);
            try
            {
                client.AsyncNotifyMessage(message);
            }
            catch
            {

            }           
        }

        static intNotifySecond(NotifyMode mode)
        {
            if (mode == NotifyMode.Wicket)
            {
                return 1;
            }
            else if (mode == NotifyMode.FiveOverOnce)
            {
                return  2;
            }
            else if (mode == NotifyMode.FiftyRunsOnce)
            {
                 return  3;
            }
            return 0;    
        }

    }
}


 Web Config:
<system.serviceModel>
    <bindings>
      <wsDualHttpBinding>
        <binding name="Bind" bypassProxyOnLocal="true" useDefaultWebProxy="true" />
      </wsDualHttpBinding>
    </bindings>
    <services>     
      <service behaviorConfiguration="returnFaults" name="CricInfoService.CricketService">
        <endpoint address="" binding="wsDualHttpBinding" bindingConfiguration="Bind"                            contract="CricInfoService.ICricketService" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8732/CricInfoService/Cric/"/>
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="returnFaults">        
          <serviceMetadata httpGetEnabled="True"/>        
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>


host the WCF service : Hosting WCF Service


Client Code :

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace CricClient
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private voidForm1_Load(object sender, EventArgs e)
        {

        }

        private voidbutton1_Click(object sender, EventArgs e)
        {
            SubscriberHandler subscribeclient1 = new SubscriberHandler(CricService.NotifyMode.Wicket, "Rajesh",listBox1);
        }

        private voidbutton2_Click(object sender, EventArgs e)
        {
            SubscriberHandler subscribeClient2 = new SubscriberHandler(CricService.NotifyMode.FiveOverOnce, "suresh", listBox2);
        }

        private voidbutton3_Click(object sender, EventArgs e)
        {
            SubscriberHandler subscribeClient3 = new SubscriberHandler(CricService.NotifyMode.FiftyRunsOnce, "Ram", listBox3);
        }
    }

    class SubscriberHandler: CricService.ICricketServiceCallback
    {
        ListBox lstobj = null;

        public SubscriberHandler(CricService.NotifyMode mode, stringname,ListBox obj)
        {
            CricService.CricketServiceClientclient = new CricService.CricketServiceClient(newSystem.ServiceModel.InstanceContext(this));
            lstobj = obj;
            bool status = client.GetNotification(mode, name);
            MessageBox.Show("Cricket Notification Activated in "+ mode.ToString() + " Mode : " + status);
        }

        public voidAsyncNotifyMessage(string message)
        {
            lstobj.Items.Add(message);
        }
    }

}



From the above code You can see the SubscriberHandler which will get the instance of each client and send the instance to the service and get the result from the server then server starts the notification from server to client.

From this article you can see the publisher and subscriber model creation from WCF using WsDualHttpBinding.