Outils pour utilisateurs

Outils du site


Panneau latéral

Accueil

Select other language :


Apprentissage

Enseignements

Enseignements Département Informatique SI5 et Master IFI

Enseignements Département Bâtiment Polytech'Nice

Autres Formations française et étrangère

Activités administratives, Ingénierie et Innovation Pédagogiques

Apprentissage Département Informatique SI5/Master 2 ingénierie informatique EUR DS4H


Recherche

Valorisation de la Recherche

Dépôts Logiciels à l’Agence de Protection des Programme (APP)

Valorisation des résultats de recherche et transfert

Diffusion de la Culture scientifique et Technologique

Communications de presse

Séminaire ENSI Tunis

Pédagogie Innovante

Relations industrielles et socio-économique

Organisation de Manifestations

  • Conférence sur les FabLabs, Alexandre Schneider, Professeur Agrégé en Génie Mécanique, Université de Reims Champagne-Ardenne Web
  • Journées UbiMob'14 Site Web

Animation de la Recherche

U-Santé

Privé

Outils

Sources d'Informations

cours:service_oriented_computing_and_web_services_2017_2018:lab_eventing_and_wstutorial:publish_subscribe_pattern_for_eventing_with_web_services

Event based Communication and Event driven Architecture with web services

The solution of the first part of this tutorial is provided below.

Add the solution(s) of the second part of this tutorial on your Github repository !

Introduction : Why Event driven Architecture ?

Classical Request–response, or request–reply, is one of the basic methods computers use to communicate with each other, in which the first computer sends a request for some data and the second computer responds to the request.

Using request/response communication, client must implement active loop to read periodically a data to refresh its value locally and detect changes.

A typical domain with such a problem is Internet of Things like for example sensors networks. In fact it's easy to understand that for N sensors, the client must send N requests periodically to test if one sensor measure changed since last requests !

Event-driven architecture (EDA), is a software architecture pattern promoting the production, detection, consumption of, and reaction to events.

An event can be defined as “a significant change in state”.

Some Middleware like MQTT are specificaly design to implement such event driven architectures.

PART 1 : Your first step by step eventing communications between Web service and Client

Events Introduction

Events allow the client or clients to be notified about something that has occurred on the service side. An event may result from a direct client call, or it may be the result of something the service monitors. The service firing the event is called the publisher, and the client receiving the event is called the subscriber.

Events in WCF

While events in WCF are nothing more than call back operations, however by their very nature, events usually imply a looser relationship between the publisher and the subscriber than a typical relationship between a client and a service. The Service firing the event is called the publisher, and the client receiving the event is called the subscriber. service typically publishes the same event to multiple subscribing clients. The publisher often does not care about the order of invocation of the subscribers, or any errors, all the publisher knows is that it should deliver the event to the subscribers. Since service does not care about the returned results from the subscribers.

Consequently, event handling operations:

  • should have void return type
  • should not have any out/ref parameters(see Appendice FAQ for explanation)
  • should be marked as one way (see Appendice FAQ for explanation)

Here we divide the exercice in three parts.

On the server side :

  • .Net Framework Class Library (EventsLib.dll): Actual Service logic, which defines a Service Contract Interface, OperationContract, and implements them, and exposes few functions to the world to use them
  • Console Application to host the WCF Service Library EventsLibHost.exe): Host the WCF library

On the client side :

  • Console Application (EventsClient.exe): Client Application which will use this service.
Be administrator to test your solution and projects

Create WCF Service Library (EventsLib.dll)

To create this project, you can simply take a “Class Library” project, while choosing from project wizard option. Let's name it “EventsLib”, it is the actual service which implements the business logic. The project already contains a file Class1.cs, let us do some house keeping, before we write any code for the service library.

  • Delete the file Class1.cs from the project workspace.
  • Add a new Interface named ICalcService to the project, a new file ICalcService.cs will be added to the project.
  • Add a new Class named CalcService to the project that will implement the ICalcService interface, a new file CalcService.cs will be added to the project.
  • Add a new Interface named ICalcServiceEvents to the project, a new file ICalcServiceEvents.cs will be added to the project.

Defining Interface ICalcServiceEvents (ICalcServiceEvents.cs)

Now Let's define interface for the events published by the service.

Interface simply publishes 2 methods which are basically events for the subscriber. Note that every method in this interface has been:

  • marked as OneWay (See appendice for example)
  • does not return any value (void)
  • has no out/ref parameter

The first method Calculated is an event for the subscriber, it is fired, when calculation is done, it also passes the result to the subscribers. along with the operands and operation type.

The second method CalculationFinished is the event, it is fired when the Calculation is finished.

The source code may be this:

using System;
using System.Text;
using System.ServiceModel;
namespace EventsLib
{
    public interface ICalcServiceEvents
    {
        [OperationContract(IsOneWay=true)]
        void Calculated(int nOp, double dblNum1, double dblNum2, double dblResult);
 
        [OperationContract(IsOneWay=true)]
        void CalculationFinished();
    }
}

Defining Interface ICalcService (ICalcService.cs)

Interface simple defines 3 methods.

void Calculate(int nOp, double dblNum1, double dblNum2);

that is the method, that is related to business logic that does the actual job.

void SubscribeCalculatedEvent () ;

void SubscribeCalculationFinishedEvent ();

that are helper methods that are called by the client to subscribe an event published by the service. As you have 2 events, so you have one method for each event.

Code may be like that :

//  Listing of ICalcService.cs
using System;
using System.Text;
using System.ServiceModel;
namespace EventsLib
{
    [ServiceContract(CallbackContract = typeof(ICalcServiceEvents))]
    public interface ICalcService
    {
        [OperationContract]
        void Calculate(int nOp, double dblNum1, double dblNum2);
 
        [OperationContract]
        void SubscribeCalculatedEvent();
 
        [OperationContract]
        void SubscribeCalculationFinishedEvent();
    }
}

Implementing ICalcService interface (CalcService.cs)

Comments :

static Action<int, double, double, double> m_Event1 = delegate { };//

static Action m_Event2 = delegate { };
  • Action keyword can be used to define a delegate, can be used to pass a method as a parameter without explicitly declaring a custom delegate.
  • Methods SubscribeCalculatedEvent() and SubscribeCalculationFinishedEvent() are as given below:
public void SubscribeCalculatedEvent()
{
    ICalcServiceEvents subscriber = 
		OperationContext.Current.GetCallbackChannel<ICalcServiceEvents>();
    m_Event1 += subscriber.Calculated;
}   

public void SubscribeCalculationFinishedEvent()
{
    ICalcServiceEvents subscriber=OperationContext.Current.GetCallbackChannel<ICalcServiceEvents>();
    m_Event2 += subscriber.CalculationFinished ; 
}
  • Gets the reference of the client side callback method, and assigns this event handler to the delegate variable m_Event1, and m_Event2. This method allows clients to do selective subscription of the exposed events.

Method public void Calculate(int nOp, double dblX, double dblY) is as follows:

public void Calculate(int nOp, double dblX, double dblY)
{
            double dblResult = 0;
            switch (nOp)
            {
                case 0: dblResult = dblX + dblY; break;
                case 1: dblResult = dblX - dblY; break;
                case 2: dblResult = dblX * dblY; break;
                case 3: dblResult = (dblY == 0) ? 0 : dblX / dblY; break;
            }
            
            m_Event1(nOp, dblX, dblY, dblResult);
            m_Event2();
}   

implements the business logic of the service, and calls the callback methods implemented at the client side, using delegates, in short, fires events.

Your code may be like that :

 //  Listing of CalcService.cs

using System;
using System.Text;
using System.ServiceModel;
 
namespace EventsLib
{
    public  class CalcService : ICalcService
    {
       static Action<int, double, double, double> m_Event1 = delegate { }; 
       static Action m_Event2 = delegate { };
 
       public void SubscribeCalculatedEvent()
       {
           ICalcServiceEvents subscriber = 
           OperationContext.Current.GetCallbackChannel<ICalcServiceEvents>();
           m_Event1 += subscriber.Calculated;
       }
        
        public void SubscribeCalculationFinishedEvent()
        {
            ICalcServiceEvents subscriber = 
            OperationContext.Current.GetCallbackChannel<ICalcServiceEvents>();
            m_Event2 += subscriber.CalculationFinished ;
        }
               
        public void Calculate(int nOp, double dblX, double dblY)
        {
            double dblResult = 0;
            switch (nOp)
            {
                case 0: dblResult = dblX + dblY; break;
                case 1: dblResult = dblX - dblY; break;
                case 2: dblResult = dblX * dblY; break;
                case 3: dblResult = (dblY == 0) ? 0 : dblX / dblY; break;
            }
            
            m_Event1(nOp, dblX, dblY, dblResult);
            m_Event2();
        }
    }
}    

Compile the class library, and the first part is complete.

put the dll of the first project in the bin directory of the self-hosted service project, in the case of lack.

Host Application (EventsLibHost.exe)

Defining Configuration for CalcService

The Host application will expose the following endpoints for the service :

  • CalcService will expose HTTP endpoint at Port 9011
  • Corresponding mex End Point (IMetadatExchange) for the HTTP end point

Application configuration files define 1 endpoint with WSDualHttpBinding at port 9011 and respective mex end point. WSDualHttpBinding is similar to the WSHttpBinding, but provides more web service features.

Defining Behavior(s) for Services

Each service behavior defines two attributes:

  • <serviceMetadata httpGetEnabled=“true”/>

Gets or sets a value that indicates whether to publish service metadata for retrieval using an HTTP/GET request, true means yes, metadata is available for retrieval using a HTTP/GET request.

  • <serviceDebug includeExceptionDetailInFaults=“true ”/>

Set IncludeExceptionDetailsInFaults to true to enable clients to obtain information about internal service method exceptions; it is only recommended as a way of temporarily debugging a service application. This property must be set to false on production servers. Once the configuration is in place.

Create the self-hosted service

(see appendice for example)

The ServiceHost class provides a host for services.

Exercice : Create the host object and open it, and wait endlessly, untill a key is pressed. when you press a key, host is closed. Main object and methods are then :

  • ServiceHost host = new ServiceHost(typeof(EventsLib.CalcService));
  • host.Open();
  • host.Close();

Create the Client Application

Exercice :

  • You can simply take a “Console based Application” project, while choosing from project wizard option. Let's name it “EventsClient”, a new Project EventsClient will be added to the workspace. While the self-hosted service is running Add a Service Reference to this project with the address of the mex endpoint of CalcService.
  • Now when you have added reference of the CalcService, now the next thing you need to do is to define an event handler for the events fired for the service. Add a new class to the client application, let's call it CalcServiceCallbackSink, it is derived from the CallBack interface of the service (ICalcServiceCallback), and simply implements the methods exposed by the Callback interface.
  • Create an object of Events Sink object, create an Instance context object passing the object of the class who implements the callback interface as an Instance Context information for the service.

CalcServiceCallbackSink objsink = new CalcServiceCallbackSink ();

InstanceContext iCntxt = new InstanceContext(objsink);

  • Create an object of the service proxy.

CalcServiceReference.CalcServiceClient objClient = new CalcServiceReference.CalcServiceClient(iCntxt);

  • Select the events you prefer to receive.

objClient.SubscribeCalculatedEvent ();

objClient.SubscribeCalculationFinishedEvent ();

  • Call the service methods.

double dblNum1 = 1000, dblNum2 = 2000 ;

objClient.Calculate (0, dblNum1, dblNum2);

dblNum1 = 2000; dblNum2 = 4000;

objClient.Calculate(1, dblNum1, dblNum2);

dblNum1 = 2000; dblNum2 = 4000;

objClient.Calculate(2, dblNum1, dblNum2);

dblNum1 = 2000; dblNum2 = 400;

objClient.Calculate(3, dblNum1, dblNum2);

  • Build and execute, and here is the output:

Correction

Here, is the solution of the first part

srcevents_wcf_ws.zip

Appendices for FAQ

What is the One-way operation mode

How to create a Self-Hosted Web Service

What are Out/Ref parameters

Action<T> Delegate

PART 2 : Advanced use of Eventing

Thanks to the previous example, create a central WS that accept data modification from “Publishers” clients and send event on these modifications to “subscribers” clients. Test it with a simple shared data like a count value, with one pupblisher and various subscribers.

cours/service_oriented_computing_and_web_services_2017_2018/lab_eventing_and_wstutorial/publish_subscribe_pattern_for_eventing_with_web_services.txt · Dernière modification: 2018/03/29 11:33 par tigli