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(NotifyMode
mode,string username);
[OperationContract(IsOneWay=true)]
void GetNotify(NotifyMode
mode, string username);
}
public interface IClientCallback
{
[OperationContract(IsOneWay=true)]
void AsyncNotifyMessage(string
message);
}
}
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 NotifyMode
Mode {set;get;}
public string
UserName {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 bool
GetNotification(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 (Exception
ex)
{
throw new
FaultException(ex.Message);
}
}
public void
GetNotify(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 (Exception
ex)
{
throw new
FaultException(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(NotifyMode
mode)
{
for (int i = 0; i
< notifylist.Count; i++)
{
CricketData data =
notifylist[i];
if (data.Mode == mode)
{
Send(data);
}
}
}
private static void Send(CricketData
data)
{
int f = NotifySecond(data.Mode);
IClientCallback
client =
data.CricketContext.GetCallbackChannel<IClientCallback>();
String message = string.Format("{1}/{0} : Runs/Wickets {2} Overs",
Wicket,
Run, Over);
try
{
client.AsyncNotifyMessage(message);
}
catch
{
}
}
static int
NotifySecond(NotifyMode mode)
{
if (mode == NotifyMode.Wicket)
{
return 1;
}
else if (mode == NotifyMode.FiveOverOnce)
{
return
2;
}
else if (mode == NotifyMode.FiftyRunsOnce)
{
return
3;
}
return 0;
}
}
}
<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 void
Form1_Load(object sender, EventArgs e)
{
}
private void
button1_Click(object sender, EventArgs e)
{
SubscriberHandler subscribeclient1 = new SubscriberHandler(CricService.NotifyMode.Wicket, "Rajesh",listBox1);
}
private void
button2_Click(object sender, EventArgs e)
{
SubscriberHandler subscribeClient2 = new SubscriberHandler(CricService.NotifyMode.FiveOverOnce, "suresh",
listBox2);
}
private void
button3_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, string
name,ListBox obj)
{
CricService.CricketServiceClient
client = new CricService.CricketServiceClient(new
System.ServiceModel.InstanceContext(this));
lstobj = obj;
bool status = client.GetNotification(mode, name);
MessageBox.Show("Cricket
Notification Activated in "+ mode.ToString() + " Mode : " + status);
}
public void
AsyncNotifyMessage(string message)
{
lstobj.Items.Add(message);
}
}
}
From this article you can see the publisher and subscriber model creation from WCF using WsDualHttpBinding.
No comments:
Post a Comment