Sie sind auf Seite 1von 18

Contents

Introduction

Part I - Basic

What is Event Notification Server(ENS)?


Multiple Protocol Support
How does it work?
Procedure to use ENS and test clients.
Limitation

Part II - Internal.

Data Structure and Algorithm


Architecture of Event Notification Server.

Publisher & Subscriber Model

Part III - Documentation of Code

Introduction

A simplified Event Notification Server allows you to be notified when an alert is


generated in a system without filtering for what type of event you are registered.In
various scenarios we need such type of publish subscribe scheme .Here a simplified
Event Notification Server is implemented in wcf using pub/sub scheme with multiple
protocol support.In this implementation if a client subscribes with a server, the client
will get all the events sent by the publisher.

Sources

I read the Juval Lowy Article on msdn magazine but the article is based on topic
based pub/sub scheme .But for many cases a simple pub/sub scheme is needed
without topic scheme .So i made many changes to the code and finally made a
simplified version,i hope that this simplified implementation with multiple protocol
support will be helpful to many men like me in their project.The code used in this
article is based on the juva's lovy article, but some parts are not changed.

Part I - Basic
What is Event Notification Server?
Event Notification Server is an “Event Notification” system. It connects programs
that provide information changes over time (publishers) with programs that want to
receive notifications of those changes (subscribers). It is the middle ware that deals
with publishers and subscribers.

Multiple Protocol Support

There are essentially two main groups applications that communicate through
networks or the Internet - client server and the and peer-to-peer. Event Notification
Server employ client server architectures for better performance.

Here the Event Notification Server expose different protocols based connectivity. A
client
based on his requirement will choose protocol to connect.

Diagram 1 - Several clients connected to a Event Notification Server with multiple


protocol.

If a client is in the same machine with Event Notification Server (ENS) then it will
connect with ENS thru Named Pipe protocol Because Named Pipe protocol is the
fastest for same machine boundary.

If a client is in the same Local Area Network (LAN) with ENS it will connect with ENS
thru TCP protocol Because TCP is a connection oriented reliable protocol.
If a client is in the same Virtual Private Network (VPN) with ENS then it will connect
with ENS thru TCP protocol Because TCP is a connection oriented reliable protocol.

If a client is in the Internet with ENS then it will connect with ENS thru HTTP protocol
Because HTTP is a firewall friendly protocol.It is unidirectional by default but using
wsdualhttp binding i get bidirectional behavior.

How does it Work?

Here each client will register himself to ENS then when an event comes to ENS then
ENS will send it to clients that are registered.
For Example we have 10 clients and all 10 clients would register to the ENS to
receive notifications (client programs are individual programs) and then whenever
the event occurs from the publisher, the ENS notifies all those clients.

Procedure to use ENS and test clients:

How to start the total System:

In the VS2008 just press F5 to launch total system and then it will be ready to go.

Event Notification Server:

Nothing will need to be configured.

It will start with machine IP on which it is started.

For event receiving purpose(publisher service)


it will open port as follows:
8000 For HTTP.
8001 for TCP.
Mypipe1 for NamedPipe

For event broadcasting purpose(subscription service)


it will open port as follows:

8003 For HTTP.


8002 for TCP.
Mypipe2 for NamedPipe

How to send event:

1. For sending a single event clicks on button “Fire a single Event”.

2. For sending auto event set the interval then click the button
“Fire Auto Event”.
How to receive event:

1. Click the “Subscribe” button of test client.

2. Then it will start to receive the events.


Limitation
Does not work under NAT.
NO authentication, encryption
No Fault Tolerance Support .
No provision to prevent DOS (Denial of Service attack) attack.

Part II - Internal.
Data Structure:

A simple List contains the list of subscribers.

Algorithm:

Decouple the publishers from the subscribers by introducing a dedicated subscription


service and a dedicated publishing service.

Subscribers that want to subscribe to events will register with the subscription
service.

Subscription service will manages the lists of subscribers.

When there is an event in publisher

o The publisher will want subscriber list form subscriber service.

o Then Publisher will send the event to each subscriber of the list.

Architecture of Event Notification Server:


Publisher & Subscriber Model

Publish/subscribe (or pub/sub) is an asynchronous messaging paradigm where


senders (publishers) of messages are not programmed to send their messages to
specific receivers (subscribers). Rather, published messages are characterized
without knowledge of what (if any) subscribers there may be. Subscribers express
interest and receive messages , without knowledge of what (if any) publishers there
are. This decoupling of publishers and subscribers can allow for greater scalability
and a more dynamic network topology.Much the same way, the publisher can only
notify subscribers it knows about. There is no way for the publisher to deliver an
event to whomever wishes to receive it, nor is there an ability to broadcast an event.
In addition, all publishers must repeatedly have the necessary code to manage the
list of the subscribers and the publishing act itself.There is no way for a subscriber to
ask that if an event is fired, the application should create an instance of the
subscriber and let it handle the event.
Setting up subscriptions has to be done programmatically.

Part III - Documentation of Code


DataContract

Collapse Copy Code


[DataContract]
public class AlertData
{
private string _SeqNo;
private string _Description;

[DataMember]
public string SeqNo { get { return _SeqNo; } set { _SeqNo = value; } }

[DataMember]
public string Description { get { return _Description; } set { _Description
= value; } }
}

Event Publishing

The publishing service exposes the events contract in an endpoint, you need to mark
the events contract as a service contract.

Collapse Copy Code


/// <summary>
/// This is the service contract of Publish Service

[ServiceContract]
interface IEvent
{
[OperationContract(IsOneWay = true)]
void OnEvent(AlertData e);
}
To provide your own publishing service, derive from IEvent and use method to
deliver the event to all subscribers.

Collapse Copy Code


[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
class Publishing : IEvent
{

/// This method is called from the publisher client to send the event.
public void OnEvent(AlertData e)
{

IEvent[] subscribers = Subscription.GetClientList();


Type type = typeof(IEvent);
MethodInfo methodInfo = type.GetMethod("OnEvent");
foreach ( IEvent subscriber in subscribers)
{
try
{
methodInfo.Invoke(subscriber, new object[] { e });
}
catch
{

}
}
}
}

Managing Registration(subscriptions):

For managing registration, I defined IRegistration interface shown in Example 1.

Collapse Copy Code


/// <summary>
/// This is the Service contract for SubscriptionService
/// </summary>
[ServiceContract(CallbackContract = typeof(IEvent))]
public interface IRegistration
{
[OperationContract]
void Register( );

[OperationContract]
void UnRegister();
[OperationContract]
string GetDateTime();
}

The callback interface is

Collapse Copy Code


/// <summary>
/// This is the service contract of Publish Service
/// </summary>
[ServiceContract]
interface IEvent
{
[OperationContract(IsOneWay = true)]
void OnEvent(AlertData e);
}

The application needs to expose its own subscription service in the form of an
endpoint that supports its specific interface of IRegistration. To do so, the application
needs to provide a service class that derives from IRegistration specify the callback
contract as a type parameter,.

Collapse Copy Code

/// This is the class for Subscription Service that is deployed to listen.

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
class Subscription : IRegistration
{

/// This the data structue that is used for pub/sub scheme.
/// Here list is used to hold the subscribers.

static List<IEvent> m_ClientList;

/// This is constructor of the class.It is used here to create the instance
/// of the pub/sub data structure
static Subscription()
{
m_ClientList = new List<IEvent>();
}
/// This method return the complete subscriber list to publisher service.

internal static IEvent[] GetClientList()


{
lock (typeof(Subscription))
{
return m_ClientList.ToArray();
}
}

/// This method is called by subscriber to register itself with Server.


/// It register the client with pub/sub service.
public void Register( )
{
lock (typeof(Subscription))
{
IEvent subscriber = OperationContext.Current.GetCallbackChannel<IEvent>();
if (m_ClientList.Contains(subscriber))
{
return;
}
m_ClientList.Add(subscriber);
}
}

/// This method is called by subscriber to Unsubscribe itself from Server.


/// It Unsubscribe the client with pub/sub service.
public void UnRegister()
{
lock (typeof(Subscription))
{
IEvent subscriber = OperationContext.Current.GetCallbackChannel<IEvent>();
m_ClientList.Remove(subscriber);
}
}

public string GetDateTime()


{
return System.DateTime.Now.ToString();
}

}
stores subscribers in a generic static list.

Collapse Copy Code


/// This the data structue that is used for pub/sub scheme.
/// Here list is used to hold the subscribers.

static List<IEvent> m_ClientList;

The Register ( ) method extracts the callback reference from the operation call
context. Then retrieves the list of subscribers for the event from the store. If the list
does not contain the subscriber, it adds it in. UnRegister() operates in a similar
manner.

Hosting

For hosting you have to expose Publishing service multiple times for multiple
protocols.

Collapse Copy Code

eventServiceHost = new ServiceHost(typeof(Publishing));

///Here diferent binding is created for different protocol.


/// For example NetTcpBinding is created for TCP protocol.
/// For example WSDualHttpBinding is created for HTTP protocol.
// For example NetNamedPipeBinding is created for Named Pipe protocol.

System.ServiceModel.Channels.Binding wsDualBindingpublish = new


WSDualHttpBinding();
System.ServiceModel.Channels.Binding tcpBindingpublish = new NetTcpBinding();
System.ServiceModel.Channels.Binding namedPipeBindingpublish = new
NetNamedPipeBinding();

///By the following line i add the address of PublishService to


eventServiceHost for
///differnt protocol
eventServiceHost.AddServiceEndpoint(typeof(IEvent),
wsDualBindingpublish,
"http://localhost:8000/PublishingServic
e/");
eventServiceHost.AddServiceEndpoint(typeof(IEvent),
tcpBindingpublish,
"net.tcp://localhost:8001/PublishingSer
vice");
eventServiceHost.AddServiceEndpoint(typeof(IEvent),
namedPipeBindingpublish,
"net.pipe://localhost/MyPipe1");

//This line is used to open pub service to listen.


eventServiceHost.Open();

For hosting you have to expose Subscription service multiple times for multiple
protocols

Collapse Copy Code


subscriptionManagerHost = new ServiceHost(typeof(Subscription));

System.ServiceModel.Channels.Binding wsDualBinding = new WSDualHttpBinding(


WSDualHttpSecurityMode.None);
System.ServiceModel.Channels.Binding tcpBinding = new
NetTcpBinding(SecurityMode.None);
System.ServiceModel.Channels.Binding namedPipeBinding = new
NetNamedPipeBinding();

///By the following line i add the address of Subscription Service


///to subscriptionManagerHost for differnt protocol
///subscriptionManagerHost.AddServiceEndpoint(typeof(IRegistration),
wsDualBinding,

subscriptionManagerHost.AddServiceEndpoint(typeof(IRegistratio
n),
wsDualBinding,
"http://localhost:8003/SubscriptionServ
ie/");
subscriptionManagerHost.AddServiceEndpoint(typeof(IRegistration
),
tcpBinding,
"net.tcp://localhost:8002/SubscriptionServi
e");
subscriptionManagerHost.AddServiceEndpoint(typeof(IRegistration
),
namedPipeBinding,
"net.pipe://localhost/MyPipe2");
//This line is used to open sub service to listen.
subscriptionManagerHost.Open();

Http Client Connection:

We know that http is unidirectional. To make it bidirectional we have to use


WSDualHttpBinding and have to open two sockets connection in client and server. so
here ClientBaseAddress is used to set client,s address to listen in client.

Collapse Copy Code


<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key ="EndpointAddress" value
="http://localhost:8003/SubscriptionServie/"/>
</appSettings>

</configuration>

WSDualHttpBinding namedpipebinding = new


WSDualHttpBinding(WSDualHttpSecurityMode.None);
EndpointAddress endpointAddress = new EndpointAddress(EndpoindAddress);
InstanceContext context = new InstanceContext(callbackinstance);
m_Proxy = new RegistrationProxy(context, namedpipebinding, endpointAddress);
string strHostName = Dns.GetHostName();
IPHostEntry ipEntry = Dns.GetHostByName(strHostName);
IPAddress[] addr = ipEntry.AddressList;
namedpipebinding.ClientBaseAddress = new Uri("http://" +
addr[0].ToString() + ":" + "4000" + "/");

Tcp Client Connection:

SecurityMode.None is used here so that it can communicate over cross domain and
over vpn.

Collapse Copy Code


<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key ="EndpointAddress" value
="net.tcp://localhost:8002/SubscriptionServie"/>
</appSettings>
</configuration>
NetTcpBinding NetTcpbinding = new NetTcpBinding(SecurityMode.None);
EndpointAddress endpointAddress = new
EndpointAddress(EndpoindAddress);
InstanceContext context = new InstanceContext(callbackinstance);
m_Proxy = new RegistrationProxy(context, NetTcpbinding,
endpointAddress);

IPC Client Connection:

Collapse Copy Code


<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key ="EndpointAddress" value ="net.pipe://localhost/MyPipe2"/>
</appSettings>
</configuration>
NetNamedPipeBinding namedpipebinding = new NetNamedPipeBinding();
EndpointAddress endpointAddress = new
EndpointAddress(EndpoindAddress);
InstanceContext context = new InstanceContext(callbackinstance);
m_Proxy = new RegistrationProxy(context, namedpipebinding,
endpointAddress);

Http Publisher Connection:

We know that http is unidirectional. To make it bidirectional we have to use


WSDualHttpBinding and have to open two sockets connection in client and server. so
here ClientBaseAddress is used to set client,s address to listen in client.

Collapse Copy Code


WSDualHttpBinding wsDualBindingpublish = new WSDualHttpBinding();
EndpointAddress endpointAddress =
new EndpointAddress("http://localhost:8000/PublishingService/");
string strHostName = Dns.GetHostName();

IPHostEntry ipEntry = Dns.GetHostByName(strHostName);

IPAddress[] addr = ipEntry.AddressList;

wsDualBindingpublish.ClientBaseAddress = new Uri("http://" +


addr[0].ToString()
+ ":" + "3000" + "/");
proxy = new PublisherProxy(wsDualBindingpublish, endpointAddress);
Conclusion

Here the code implement most simple scenario of pub/sub scheme without topic
based which is helpful in many scenarios.

In the future post i will give fault tolerance implementation of this.

and then i will show how windows and certificate authentication can be implemented
using this implementation.

Referance

Das könnte Ihnen auch gefallen